我正在研究一個應用程序,以便能夠監視3x3(如此9屏幕)視頻牆上的生產信息。我正在處理的屏幕集之一現在檢索信息,然後在屏幕上顯示格式。它需要大約2秒鐘來檢索和格式化這些數據(只是粗略的猜測,而不是實際測量)。因爲它一個接一個地顯示9個屏幕,所以切換到這個屏幕集有非常明顯的時間。驅動這個視頻牆的個人電腦有8個處理核心,所以儘管一個處理器正在努力完成所有這些工作,但仍有大量處理能力處於閒置狀態。vb.Net:在BackgroundWorker中創建UI
我的第一個想法是我需要使用多線程。不幸的是,我對這個概念很陌生。我真的只用過一次。我試着創建一個BackgroundWorker並讓DoWork例程生成我的UI。不幸的是,它第一次嘗試創建UI元素時崩潰(Dim grLine as New Grid
)。我確實設法通過虛擬DoWork
例程並在RunWorkerCompleted
例程中生成所有我的UI。這確實可以讓我的空白窗口立即顯示出來,但是我所生成的所有用戶界面都沒有顯示出來,直到它全部呈現完畢。
這裏是什麼,我試圖做一個非常清理版本:
For i As Integer = 1 to 9
Dim win As New MyCustomWindow
win.DisplayScreen = i ' This function in MyCustomWindow sets the Bounds
win.MyShow({1, 2}) ' Sample args
Globals.VideoWall.Windows(i) = win
Next
的MyCustomWindow類:
Class MyCustomWindow
Public Sub MyShow(a() as Integer)
Me.Show() ' Has a "Loading..." TextBlock
Dim bw as New ComponentModel.BackgroundWorker
AddHandler bw.DoWork, AddressOf Generate_UI_DoWork
AddHandler bw.RunWorkerCompleted, AddressOf Generate_UI_Complete
bw.RunWorkerAsync(a)
End Sub
Private Sub Generate_UI_DoWork((sender As Object, e As ComponentModel.DoWorkEventArgs)
' Pass our arguments to the Complete routine.
e.Result = e.Argument
End Sub
Private Sub Generate_OpsMarket_Complete(sender As Object, e As ComponentModel.RunWorkerCompletedEventArgs)
Dim IDs() as Integer
IDs = e.Result
Dim grLine As New Grid ' We crash here if this code is in DoWork instead of RunWorkerCompleted
For Each id As Integer In IDs
grLine.RowDefinitions.Add(New RowDefinition)
Dim txt as New TextBlock ' For a header
grLine.Children.Add(txt)
grLine.RowDefinitions.Add(New RowDefinition)
Dim MyCtrl as New MyCustomControl()
MyCustomControl.GetData(id)
grLine.Children.Add(MyCtrl.MyGrid)
txt.Text = MyCtrl.Header
Next
txLoading.Visibility = Visibility.Hidden
grRoot.Children.Add(grLine)
End Sub
End Class
我試圖在代碼中留下足夠的細節,所以希望它」我將會明白我正在努力完成什麼,但保持足夠小以至於不會讓人無法抗拒。
編輯補充:
的大部分工作發生在MyCustomControl.GetData(id)
...該子下載從web服務器的數據(JSON格式),解析JSON,然後生成的行(3)和列(30或31,取決於月份),並填寫從Web服務器收到的數據。
歡迎來到多線程世界!一些事情。您希望充分利用8個邏輯內核,而要做到這一點的方法是使用8個或更多線程來完成一系列可以分離成不同工作單元的工作。例如,你想計算從1到100萬的所有整數的sqrt。這些是不同的工作單元,每個工作單元都可以獨立執行,因此您可以讓操作系統決定如何分配工作。單一的後臺工作者仍然只能在單線程(單核)下運行,因此在那裏沒有太多好處。續... – djv
表單應用程序中的背景工作者的好處是允許在UI線程以外的線程上完成工作。這將允許UI繼續刷新並響應輸入,而不會通過處理非UI內容堵塞它。您可能確實想在非UI線程上進行計算,因爲它是.NET中UI編程的一個非常重要的部分。但爲了快速完成這些計算(通過利用8個邏輯內核),您希望多線程工作在後臺工作中完成。如果這是有道理的,我可以寫一個簡單的例子讓你走。 – djv
這並不是因爲我需要保持所有8個內核的繁忙,而是我現在做事情的方式花費的時間比應該需要的時間長。我爲9個不同的屏幕一個接一個地生成用戶界面,每個屏幕大約需要2秒。在我最初的代碼中,上面'Generate_OpsMarket_Complete'內的示例中的所有內容都在'MyShow'中......通過將大量代碼移動到BackgroundWorker,希望所有9屏幕的UI可以並行生成而不是按順序生成。 – StarDestroyer