所以,我有麻煩實現一個單獨的線程。這是因爲我有一個簡單的類,並在其中開始一個新的線程。所以,因爲它不是任何形式,所以我沒有找到任何方法讓它在UI線程中調用函數。線程:從一個單獨的線程調用委託(VS2010)
所以,我不能使用Invoke
方法。有沒有辦法從另一個線程調用一個函數?
所以,我有麻煩實現一個單獨的線程。這是因爲我有一個簡單的類,並在其中開始一個新的線程。所以,因爲它不是任何形式,所以我沒有找到任何方法讓它在UI線程中調用函數。線程:從一個單獨的線程調用委託(VS2010)
所以,我不能使用Invoke
方法。有沒有辦法從另一個線程調用一個函數?
我打算假設你有暴露於你的類的事件,並且你希望事件處理程序在UI線程上執行。我想你可以有一個調用者指定的回調。無論哪種方式,我將在下面描述的模式會在兩種情況下工作
一種方式來實現這一目標是讓你的班級接受ISynchronizeInvoke
實例。 Form
和Control
實例實現此接口,因此可以使用對其中一個的引用。你可以使它成爲一個約定,如果沒有指定一個實例,則通過在類上引發事件來執行的事件處理程序將在工作線程中執行,而不是在託管ISynchronizeInvoke
實例(通常是表單或控件)的線程中執行。
Public Class YourClass
Private m_SynchronizingObject As ISynchronizeInvoke = Nothing
Public Sub New(ByVal synchronizingObject As ISynchronizeInvoke)
m_SynchronizingObject = synchronizingObject
End Sub
Public Property SynchronizingObject As ISynchronizeInvoke
Get
Return m_SynchronizingObject
End Get
Set(ByVal value As ISynchronizeInvoke)
m_SynchronizingObject = value
End Set
End Property
Private Sub SomeMethodExecutingOnWorkerThread()
RaiseSomeEvent()
End
Private Sub RaiseSomeEvent()
If Not SychronizingObject Is Nothing AndAlso SynchronizingObject.InvokeRequired Then
SynchronizingObject.Invoke(New MethodInvoker(AddressOf RaiseSomeEvent)
End If
RaiseEvent SomeEvent
End Sub
End Class
首先要注意的是,您不必指定同步對象。這意味着您不必擁有Form
或Control
參考。如果沒有指定,則將在工作線程上產生SomeEvent
。這與System.Timers.Timer
類中使用的模式相同。
謝謝,我現在問形式參考,它的工作原理。 :) – 2011-06-11 14:10:21
嘗試在你的類中公開一些事件,當你需要通知你的UI時觸發它們,最後讓你的UI組件註冊到這些事件中,當事件被觸發時,監聽器方法將被執行。那裏你可以使用Control.Invoke或Control.BeginInvoke在UI線程上執行你的代碼。
爲什麼你不能在控件上調用'Invoke'或'BeginInvoke'? – 2011-06-10 21:38:35
因爲我沒有任何控制權。我正在開發一個圖書館。 :) – 2011-06-10 22:00:41
如果您需要調用一個委託的線程上,一個控制上創建你將不得不找出哪個線程是。最簡單的方法是讓你的庫的消費者傳遞給控制引用到對象在它的構造函數或設置屬性。 – 2011-06-11 00:59:55