2011-06-10 122 views
0

所以,我有麻煩實現一個單獨的線程。這是因爲我有一個簡單的類,並在其中開始一個新的線程。所以,因爲它不是任何形式,所以我沒有找到任何方法讓它在UI線程中調用函數。線程:從一個單獨的線程調用委託(VS2010)

所以,我不能使用Invoke方法。有沒有辦法從另一個線程調用一個函數?

+0

爲什麼你不能在控件上調用'Invoke'或'BeginInvoke'? – 2011-06-10 21:38:35

+0

因爲我沒有任何控制權。我正在開發一個圖書館。 :) – 2011-06-10 22:00:41

+0

如果您需要調用一個委託的線程上,一個控制上創建你將不得不找出哪個線程是。最簡單的方法是讓你的庫的消費者傳遞給控制引用到對象在它的構造函數或設置屬性。 – 2011-06-11 00:59:55

回答

0

我打算假設你有暴露於你的類的事件,並且你希望事件處理程序在UI線程上執行。我想你可以有一個調用者指定的回調。無論哪種方式,我將在下面描述的模式會在兩種情況下工作

一種方式來實現這一目標是讓你的班級接受ISynchronizeInvoke實例。 FormControl實例實現此接口,因此可以使用對其中一個的引用。你可以使它成爲一個約定,如果沒有指定一個實例,則通過在類上引發事件來執行的事件處理程序將在工作線程中執行,而不是在託管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 

首先要注意的是,您不必指定同步對象。這意味着您不必擁有FormControl參考。如果沒有指定,則將在工作線程上產生SomeEvent。這與System.Timers.Timer類中使用的模式相同。

+0

謝謝,我現在問形式參考,它的工作原理。 :) – 2011-06-11 14:10:21

0

嘗試在你的類中公開一些事件,當你需要通知你的UI時觸發它們,最後讓你的UI組件註冊到這些事件中,當事件被觸發時,監聽器方法將被執行。那裏你可以使用Control.Invoke或Control.BeginInvoke在UI線程上執行你的代碼。