|
分類:[VB.NET (Windows)]
VB2005 ExpressをWinXP SP2上で使用しています。
BackgroundWorkerを使って別スレッドで装置から温度取得し、
フォーム(MainMenu)にイベントで通知したいのですが、
イベントを受けたフォーム側で例外(InvalidOperationException)が発生してしまいます。
別スレッドからフォーム(のコントロール)にアクセスするにはどのようにしたらいいのでしょう?
ご教授願います。以下、長いですがソースです。
Public Class MainClass
Public Shared Sub Main()
Dim observer As TempObserver
observer = TempObserver.GetInstance
observer.StartObserve() '温度取得開始
Dim frm As New MainMenu
frm.ShowDialog()
End Sub
End Class
'温度を表示するフォーム
Public Class MainMenu
Private Sub MainMenu_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim observer As TempObserver = TempObserver.GetInstance
AddHandler observer.TemparatureChange, AddressOf TemparatureChange
End Sub
'TempObserverのTemparatureChangeイベントを受ける
Private Sub TemparatureChange(ByVal temparature)
Me.lblTemparature.Text = Format(temparature, "0.0") & "℃" 'この行で例外発生(InvalidOperationException)
End Sub
End Class
'装置から温度取得するクラス
Public Class TempObserver
Private temparature As Double '温度
Private worker As System.ComponentModel.BackgroundWorker '使用するBackgroundWorker
Private Shared instance As TempObserver 'このクラスのインスタンス
Public Event TemparatureChange(ByVal temparature) '温度変化の通知イベント
Public Shared Function GetInstance() As TempObserver
If (instance Is Nothing) Then
instance = New TempObserver
End If
Return instance
End Function
'SingletonにしたいのでPrivate
Private Sub New()
temparature = 0
worker = New System.ComponentModel.BackgroundWorker
worker.WorkerSupportsCancellation = True 'キャンセル処理を受け付けるように設定
AddHandler worker.DoWork, AddressOf ObserveTemparature 'DoWorkイベントをObserveTemparatureに関連付ける
AddHandler worker.RunWorkerCompleted, AddressOf CallBack 'RunWorkerCompletedイベントをCallBackに関連付ける
End Sub
'温度監視を開始する
Public Sub StartObserve()
If (worker.IsBusy = False) Then
worker.RunWorkerAsync()
End If
End Sub
'温度を観測する(BackgroundWorkerのDoworkイベント)
Private Sub ObserveTemparature(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
System.Threading.Thread.Sleep(1000)
'(温度取得処理)
'temparatureに温度が代入される
End Sub
'BackgroundWorkerのCompleteEvent(温度を通知する)
Protected Sub CallBack(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
RaiseEvent TemparatureChange(temparature)
Call StartObserve()
End Sub
End Class
|