熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

使用.NET多線程技術顯示實時股票信息

2022-06-13   來源: .NET編程 
本文的內容是學習如何使用多線程技術建立應用程序使應用程序在執行時間和資源密集型後台事務的時候用戶界面(UI)仍然保持活動狀態

  多線程技術(multithreading)是編程中最強大的概念之一使用多線程技術你可以把復雜的事務拆分到彼此獨立執行的多個線程之中良好的多線程應用程序是自然地同步的類似於Web服務調用在默認情況下Web服務調用屬於阻塞(blocking)調用即調用者(caller)的代碼停止執行直到Web服務返回結果為止但是由於Web服務調用通常很慢就可能導致客戶端性能降低除非你采用特殊的步驟使調用異步進行

  本文講解的是如何建立一個圖表應用程序從這個例子中你可以看到如何在不影響客戶端UI的時候異步地調用Web服務示例代碼利用Chart FX組件使用圖形來顯示股票信息當然讀者也可以使用NET編寫的免費圖表類庫

  建立一個Web服務

  示例代碼需要訪問假想的股票報價Web服務我們在Visual Studio NET 中建立一個Web服務把它命名為StockWS這個Web服務由一個叫做getPrice()的Web方法組成該方法只接受一個股票編碼參數

Public Function getPrice(ByVal stock As String) As Single
 Return Rnd() *
End Function
  不管被請求的股票是什麼getPrice()方法都生成一個隨機的價格它的唯一目標是模擬一個返回特定股票價格的真實的Web服務
盡管本文使用的是一個成型的Web服務來進行演示的但是你可以輕易地替換這個Web服務以顯示真正的股票信息

  使用Chart FX組件顯示圖形

  在建立上面的Web服務項目之後先給解決方案浏覽器添加一個Windows應用程序項目(叫做Stock Quote股票報價)給該項目增加一個對前面所建立的Web服務的引用解決方案浏覽器現在應該如圖所示


使用.NET多線程技術顯示實時股票信息
解決方案浏覽器中的項目-圖中顯示了StockWS Web服務項目和
  Windows窗體項目Stock Quote

  為了建立本文的示例項目你必須從下載和安裝Chart FX組件天試用版在安裝這個繪圖組件之後你可以在Visual Studio NET 的工具盒中看到它(如圖所示)


使用.NET多線程技術顯示實時股票信息
工具盒中的Chart組件你需要從網站上下載並安裝Chart FX組件天試用版
  在該Windows應用程序默認的Form用下面一些控件填充該窗體如圖所示

  · Chart
  · ComboBox
  · Button


使用.NET多線程技術顯示實時股票信息
Stock Quote主窗體-圖中顯示了添加適當的控件之後窗體樣式
  Chart(繪圖)組件為定制自己的行為和外觀提供了很多選項你可以使用向導(位於屬性窗體底部如圖所示)格式化這個Chart組件


使用.NET多線程技術顯示實時股票信息
Chart組件的格式化向導-該向導為Chart組件提供了大量的格式化選項

  使用示例的最簡單的方法是把下面一些Chart屬性復制並粘貼到Windows窗體設計器生成的代碼段中


Chart
MeChartAxisXStaggered = True
MeChartAxisXStep =
MeChartAxisYStep =
MeChartBackObject = GradientBackground
MeChartDataStyle =SoftwareFXChartFXDataStyleReadXValues
MeChartDesignTimeData = _
C:\Program Files\ChartFX for NET \Wizard\XYZerotxt
MeChartGallery = SoftwareFXChartFXGalleryLines
MeChartInsideColor = SystemDrawingColorTransparent
MeChartLineWidth =
MeChartLocation = New SystemDrawingPoint( )
MeChartMarkerShape =SoftwareFXChartFXMarkerShapeNone
MeChartName = Chart
MeChartNSeries =
MeChartNValues =
MeChartPalette = HighContrastHighContrast
MeChartPointLabels = True
MeChartSize = New SystemDrawingSize( )
MeChartTabIndex =
MeChartTitlesAddRange(New _
SoftwareFXChartFXTitleDockable(){TitleDockable})
  同時把下面一些數據項添加到組合框控件中MSFTSUNYHOOGE你可以在Form_Load事件中進行這樣的操作

MecmbStocksItemsAddRange(New String() {MSFT SUN YHOO GE})  激活圖形

  下一步導入下面的名字空間(在代碼窗口的頂部)

Imports SoftwareFXChartFX
Imports SystemThreading
  定義用於線程的全局變量t:

Dim t As Thread
  在Chart_Load事件中初始化Chart組件

Private Sub Chart_Load(ByVal sender As _
SystemObject ByVal e As SystemEventArgs) Handles ChartLoad
 x軸上每隔點顯示時間
 ChartAxisXStep =
 每個點之間用象素間隔
 ChartAxisXPixPerUnit =
 使圖表可以滾動
 ChartScrollable = True
 打開和關閉通訊管道
 ChartOpenData(CODValues CODUnknown)
 ChartCloseData(CODValues)
End Sub
  給當前的窗體添加一個叫做StockQuote的類StockQuote類調用前面的Web服務並用返回的股票價格來更新圖表

Public Class StockQuote
 組件中圖形的數量
 Const NUM_SERIES =

 Private lastPoint As Integer =
 Dim stockPrice As Single

 Private pStockSymbol As String
 Private pStockSeries As Integer =
 Private pChartControl As Chart

 WriteOnly Property StockSymbol()
  Set(ByVal Value)
   pStockSymbol = Value
  End Set
 End Property

 WriteOnly Property ChartControl()
  Set(ByVal Value)
   pChartControl = Value
  End Set
 End Property

 Public Sub InvokeWebService()
  Dim ws As New StockWSService

  For i As Integer = To
   stockPrice = wsgetPrice(pStockSymbol)
   pChartControlInvoke(New _
myDelegate(AddressOf updateChart) New Object() {})
   繼續之前等待秒鐘
   ThreadSleep()
  Next
 End Sub

 Public Delegate Sub myDelegate()
  Public Sub updateChart()
  pChartControlOpenData(CODValues NUM_SERIES CODUnknown)
  pChartControlValue(pStockSeries lastPoint) = stockPrice
  顯示x軸上的時間
  pChartControlAxisXLabel(lastPoint) = DateTimeNowToShortTimeString
  lastPoint +=
  pChartControlCloseData(CODValues)
  把滾動條移到最右邊
  pChartControlAxisXScrollPosition = pChartControlAxisXScrollSize
 End Sub

End Class

  你通過StockSymbol屬性把需要的股票編碼傳遞給StockQuote類並使用ChartControl屬性設置圖表更新InvokeWebService()方法在循環(示例中設置為)中周期性地調用上面的Web服務由於這個類會在一個單獨的線程中執行你必須非常小心以確保自己不會自動地更新某個Windows控件因為Windows控件並不是線程安全的(threadsafe)作為代替你必須使用委托並調用自己希望更新的控件上的Invoke()方法代碼每秒鐘調用Web服務一次這是由ThreadSleep()語句設置的

  為了啟動線程用最新的股票信息更新圖表獲取股票報價按鈕的點擊(Click)事件增加下面的代碼


Private Sub btnGetStockQuote_Click(ByVal sender As SystemObject _
ByVal e As SystemEventArgs) Handles btnGetStockQuoteClick
 Dim sq As New StockQuote
 sqStockSymbol = cmbStocksSelectedItem
 sqChartControl = Chart
 t = New Thread(AddressOf sqInvokeWebService)
 tStart()
End Sub
  把調用該Web服務的代碼打包為一個類的主要原因是Thread類構造函數只能接受一個ThreadStart委托(啟動線程的方法的委托)不存在可以接受多個參數值的重載的ThreadStart()方法因此把多個參數傳遞到一個線程中的唯一途徑是把調用的相關代碼打包為一個類接著你就可以通過這個類的參數來傳遞參數

  按F測試這段代碼選擇一只股票並點擊獲取股票報價按鈕你現在可以移 動窗口了(即UI並沒有被重復的Web服務調用鎖死)並且同時可以看到圖表一直在用最新的股票信息更新(圖所示)


使用.NET多線程技術顯示實時股票信息(2)
測試該應用程序-當你選擇某只股票編碼並點擊獲取股票報價按鈕的時候重復調用Web服務的結果顯示在圖表中但是由於該Web服務運行在後台線程上調用它不會影響正常的UI操作 顯示多只股票的價格

  你已經看到了如何在保證應用程序的UI不停頓的情況下異步地調用Web服務了但是你還可以增強該應用程序來同時顯示多個信息

  在同一個窗體中增加另一組控件(ChartFX組合框和按鈕)和標簽暫停停止按鈕(如圖所示)


使用.NET多線程技術顯示實時股票信息(3)
增強的多股票窗體-此圖顯示了你需要添加到默認窗體上以同時顯示兩只股票圖形的新控件
  這個增強的示例同時顯示了兩個圖形還要顯示用於顯示第二個圖形的線程的狀態信息

  添加第二個全局變量t

Dim t t As Thread
  示例項目使用計時器控件(Timer在工具箱中)來顯示第二個線程的狀態信息把計時器拖放到窗體上並把它的Interval屬性設置為這使該計時器的Tick事件每半秒鐘(毫秒)調用一次Tick事件處理程序中的代碼更新了標簽控件lblThreadStatus中的線程狀態信息

Private Sub Timer_Tick(ByVal sender As SystemObject _
ByVal e As SystemEventArgs) Handles TimerTick
 lblThreadStatusText = Thread state: & _
tThreadStateToString
End Sub
  第二個圖表也使用與第一個圖表相同的初始化代碼

Private Sub Chart_Load(ByVal sender As SystemObject _
ByVal e As SystemEventArgs) Handles ChartLoad
 在x軸上每點顯示時間
 ChartAxisXStep =
 每個點之間用個象素分隔
 ChartAxisXPixPerUnit =
 使圖表可以滾動
 ChartScrollable = True
 打開和關閉通訊管道
 ChartOpenData(CODValues CODUnknown)
 ChartCloseData(CODValues)
End Sub

  你點擊第二個圖表的獲取股票報價按鈕的時候代碼建立一個新的線程同時激活計時器這樣窗體才能夠顯示線程的狀態信息


Private Sub btnGetStockQuote_Click(ByVal sender As SystemObject _
ByVal e As SystemEventArgs) Handles btnGetStockQuoteClick
 Dim sq As New StockQuote
 sqStockSymbol = cmbStocksSelectedItem
 sqChartControl = Chart
 t = New Thread(AddressOf sqInvokeWebService)
 tStart()

 激活暫停和停止按鈕
 btnPauseContinueEnabled = True
 btnStopEnabled = True
 激活計時器控件
 TimerEnabled = True
End Sub
  按F測試這兩個圖表(圖所示)為每個圖表選擇一只股票你將看到這兩個圖表同步顯示


使用.NET多線程技術顯示實時股票信息(3)
增強的兩圖表應用程序增強的版本同時顯示了兩個圖表
  當第二個線程運行的時候你可以注意到其狀態在Running和WaitSleepJoin之間交替這是因為某個線程要麼在執行(Running)要麼在睡眠(WaitSleepJoin)當該線程被暫停的時候它的狀態是WaitSleepJoinSuspended當該線程被取消的時候它的狀態先是AbortRequested接著變成了Stopped

  如果要暫停該線程需要首先檢測運行中線程的狀態然後使用Suspend()方法在暫停一個線程之後你可以使用Resume()方法繼續執行它

Private Sub btnPauseContinue_Click(ByVal sender As SystemObject _
ByVal e As SystemEventArgs) Handles btnPauseContinueClick
如果線程處於睡眠和運行狀態就掛起它
If tThreadState = ThreadStateWaitSleepJoin _
 Or tThreadState = ThreadStateRunning Then
 tSuspend()
 btnPauseContinueText = Continue
Else
  繼續該線程
 tResume()
 btnPauseContinueText = Pause
End If
End Sub
  停止線程則使用Abort()方法

Private Sub btnStop_Click(ByVal sender As SystemObject _
ByVal e As SystemEventArgs) Handles btnStopClick
Try
 If Not tThreadState = ThreadStateStopped Then
  btnPauseContinueEnabled = False
  btnStopEnabled = False
  tAbort()
 End If
Catch ex As Exception
 MsgBox(exToString)
End Try
End Sub
  通過運行示例項目你會發現自己已經能夠使用多線程技術建立應用程序使應用程序在執行後台事務的時候仍然保持響應盡管本文的示例使用的是Web服務但是相同的原則也可以應用於其它類型的後台事務例如你可以改變這個應用程序以讀取外部設備(例如溫度計或血壓計監視設備)的數據


From:http://tw.wingwit.com/Article/program/net/201311/11368.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.