2008-11-15 139 views
1

我遇到了一些問題,從非UI線程引發的事件,我不希望必須處理如果me.invokerequired每個事件處理程序添加到在Form1中的線程。從線程安全地提高事件

我確定我已經閱讀過某處如何使用委託事件(在SO上),但我無法找到它。

Public Class Form1 

    Private WithEvents _to As New ThreadedOperation 

    Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button.Click 
     _to.start() 
    End Sub 

    Private Sub _to_SomthingHappend(ByVal result As Integer) Handles _to.SomthingHappend 
     TextBox.Text = result.ToString //cross thread exception here 
    End Sub 

End Class 

Public Class ThreadedOperation 

    Public Event SomthingHappend(ByVal result As Integer) 
    Private _thread As Threading.Thread 

    Public Sub start() 
     If _thread Is Nothing Then 
      _thread = New Threading.Thread(AddressOf Work) 
     End If 
     _thread.Start() 
    End Sub 

    Private Sub Work() 
     For i As Integer = 0 To 10 
      RaiseEvent SomthingHappend(i) 
      Threading.Thread.Sleep(500) 
     Next 
    End Sub 

End Class 

回答

2

你從Control派生你的類。有點不尋常,但是如果控件實際上託管在窗體上,則可以使用Me.Invoke()來編組呼叫。例如:

Private Delegate Sub SomethingHappenedDelegate(ByVal result As Integer) 

    Private Sub Work() 
    For i As Integer = 0 To 10 
     Me.Invoke(New SomethingHappenedDelegate(AddressOf SomethingHappenedThreadSafe), i) 
     Threading.Thread.Sleep(500) 
    Next 
    End Sub 

    Private Sub SomethingHappenedThreadSafe(ByVal result As Integer) 
    RaiseEvent SomthingHappend(result) 
    End Sub 

如果該類對象實際上並非一個形式託管,你需要一個參考傳遞到形式,以便它可以調用的invoke():

Private mHost As Form 

    Public Sub New(ByVal host As Form) 
    mHost = host 
    End Sub 

和使用mHost.Invoke()。或BeginInvoke()。

本書的最後一招是使用主啓動表單作爲同步對象。這不是完全安全的,但在99%的情況下工作:

Dim main As Form = Application.OpenForms(0) 
    main.Invoke(New SomethingHappenedDelegate(AddressOf SomethingHappenedThreadSafe), i) 

你要謹慎,在WF防止OpenForms()的準確跟蹤開放的形式,當他們得到動態重建的錯誤。

+0

我已經與第二個建議,傳遞主機控制(我傳入一個控制對象,而不是一個表單,雖然)。謝謝 – Pondidum 2008-11-15 20:49:23

1

如果您想簡化所有這些,可以使用一個名爲BackgroundWorker的類來處理GUI線程編組。

+0

是的,我知道/使用Background Worker很多,但是這個組件需要更好地控制它的線程, – Pondidum 2008-11-15 20:28:05