我正在做一個WPF .NET 3.5應用程序,它執行幾個長任務,我想使UI線程分離線程來處理數據,然後在完成更新時UI中的標籤。我遇到的問題是我使用兩個參數的功能,我正在努力解決如何在一個線程中調用帶有多個參數的函數並更新UI。Threaded Function有多個參數並返回數據
我一直在玩弄使用Delegate Sub來調用函數(它位於一個單獨的類),我的代碼也試圖從調用線程的函數返回一個數據集來更新UI,但我不確定這是否是實現此目標的最佳實踐,或者我應該使用調度程序來調用UI來更新UI(反饋將不勝感激)。
我的代碼如下。
Private Delegate Sub WorkHandler(ByVal input1 As String, ByVal input2 As String)
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim test_helper As New test_global
Dim worker As New WorkHandler(AddressOf test_helper.getWeatherData)
worker.BeginInvoke("IDA00005.dat", "Adelaide", AddressOf weatherCallBack, Nothing)
' The following is what I was using prior to attempting to work with threads, do I continue to update the UI here getting the called function to return a dataset, or do I have the called function do the UI updating?
'Dim ls As DataSet = test_helper.getWeatherData("IDA00005.dat", "Adelaide")
'Dim f_date As String = ls.Tables("weather").Rows(1).Item(3).ToString
End Sub
Public Sub weatherCallBack(ByVal ia As IAsyncResult)
CType(CType(ia, Runtime.Remoting.Messaging.AsyncResult).AsyncDelegate, WorkHandler).EndInvoke(ia)
End Sub
而我的作用,我試圖調用如下:
Class test_global
Public Sub getWeatherData(ByVal filename As String, ByVal location As String) 'As DataSet
...
End Sub
End Class
我的問題是,如果我是有調用線程更新UI,我怎麼有被調用線程要返回一個數據集,或者如果被調用的線程要更新UI,我該如何去做到這一點?
更新:
按照提供的recomendations,我impletemented這引起了DoWork的和RunWorkerCompleted事件來獲取數據,並更新了UI,分別一個BackgroundWorker。我更新的代碼如下:
Class Weather_test
Implements INotifyPropertyChanged
Private WithEvents worker As System.ComponentModel.BackgroundWorker
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(ByVal info As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
End Sub
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim test_helper As New test_global
Dim worker = New System.ComponentModel.BackgroundWorker
worker.WorkerReportsProgress = True
worker.WorkerSupportsCancellation = True
Dim str() = New String() {"IDA00005.dat", "Adelaide"}
Try
worker.RunWorkerAsync(str)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub worker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles worker.DoWork
Dim form_Helpder As New test_global
Dim ds As DataSet = form_Helpder.getWeatherData(e.Argument(0), e.Argument(1))
e.Result = ds
End Sub
Private Sub worker_Completed(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles worker.RunWorkerCompleted
If e.Error IsNot Nothing Then
MsgBox(e.Error.Message)
Else
...
NotifyPropertyChanged("lbl_minToday")
...
End If
End Sub
End Class
然後我有一個單獨的類我的函數獲取和處理數據。
我能夠調試在Visual Studio 2010中的代碼和窗體顯示,但標籤沒有更新,當我在RunWorkerAsync行放置一個斷點時,該行被調用並且Window_Loaded子完成,但看起來沒有的DoWork或RunWorkerCompleted事件被調用(至少該函數不是)。
任何人都可以提供一些幫助我如何調試代碼,看看爲什麼這些函數不被調用?
另外,上述代碼是在答案中推薦的正確方法嗎?
提供的任何援助將不勝感激。
馬特
我已經更新了這個問題,我已經按照推薦實現了BackgroundWorker,但是我遇到了兩個函數來處理DoWork和RunWorkerCompleted事件的問題。 – Lima 2011-01-13 11:47:35