私はWPF .NET 3.5アプリケーションで作業していますが、データを処理するUIスレッドとは別のスレッドを作成したい場合があります。 UIのラベル私が抱えている問題は、私が持っている関数が2つのパラメータを使い、スレッド内の複数のパラメータを持つ関数を呼び出してUIを更新する方法を考えるのに苦労していることです。スレッド関数には複数のパラメータがあり、データを返します
Delegate Subを使用して関数を呼び出す(これは別のクラスにあります)、私のコードは呼び出し元のスレッドの関数からデータセットを返して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
そして、私は呼び出そうとしています私の機能は以下のとおりである:私はUIを更新するために、呼び出し元のスレッドを持っていた場合
Class test_global
Public Sub getWeatherData(ByVal filename As String, ByVal location As String) 'As DataSet
...
End Sub
End Class
私の問題があり、私はと呼ばれる糸を持っていますかデータセットを返すか、呼び出されたスレッドがUIを更新するかどうかを確認するにはどうすればよいですか?
更新:提供アーティスト同士のコラボレーションに続き
、私はDoWorkを上げるのBackgroundWorkerをimpletementedそれぞれ、データを取得し、UIを更新するために、イベントをRunWorkerCompletedています。私の更新されたコードは次のようになります:
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イベントを処理する2つの関数を取得する際に問題が発生しています。 – Lima