2008-11-15 108 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