2011-07-22 43 views
1

我還在計劃階段,所以我沒有完整的代碼來顯示。但是我很好奇如果想要在不同程序集之間同步線程,將如何使用manualresetevent。例如,我在執行task1()的assembly1中編寫了classA。接下來,我在Assembly2中創建另一個classB,創建一個線程來運行classA.task1()。我想讓classB等到classA完成。重要的是(我們假設)我在一個單獨的線程上運行它。總之,一個代碼片段看起來像:我可以在程序集之間使用ManualResetEvent嗎?

Assembly2.ClassB:

private void main() { // for brevity 
    Thread newThread = new Thread(new ThreadStart(assembly1.classA.task)); 
    newThread.Start(); 
    // Wait until some process in classA.task() is done 

    if(classA.mySocket.Connected) { 
     // this may never occur because task1() didn't complete it's job 
    } 

    // do the rest 
} 

Assembly1.ClassA

public Socket mySocket; 

public void task1() { 
    // must stop all other threads until these lines have 
    // been processed 

    // create socket, and connect to remote endpoint 

    // Ok, to signal other threads to continue. 
    startReceiving(); 
} 

private void startReceiving() { 
    while(IsValid) { 
     mySocket.Receive(); // 
    } 
} 

我需要在這兩個類創建ManualResetEvents?這如何工作?

謝謝!

編輯: 我已經更新的代碼更有效的例子,請不要介意語法,我只是想傳達出的主意。

+0

您應該只需要創建在B中的一個手動重置事件。在新線程上調用task1並等待它結束 – tam

回答

2

是的,這很好,但是您需要跨兩個對象共享ManualResetEvent的實例。您可以通過Thread上的構造函數傳遞此共享實例,其中需要ParameterizedThreadStart

但是,如果你正在做的是等待,直到newThread完成後,只需使用Thread.Join

newThread.Start(); 
newThread.Join(); 
+0

我可以嘗試ParameterizedThreadStart。正如我對dtb所說的,這個新線程在完成之前可能會持續很長時間,因爲在同一個例程中只有幾行代碼需要保護。 – EDJ

2

Assembly1.ClassA代碼不知道,這就是所謂的從Assembly2.ClassB一個單獨的線程,所以我d認爲引入一種機制,其中Assembly1.ClassA.task1表明它已完成,這是一種糟糕的風格。

您的方案,它看起來像你只需要調用Thread.Join

的Thread.join方法

塊調用線程,直到某個線程終止

例:

private void Main() 
{ 
    Thread newThread = new Thread(new ThreadStart(Assembly1.ClassA.Task1)); 

    // Start thread 
    newThread.Start(); 

    // Wait until the invoked method returns 
    newThread.Join(); 

    // Do the rest 
    ... 
} 

請注意,這只是一樣

private void Main() 
{ 
    // Invoke method and wait until invoked method returns 
    Assembly1.ClassA.Task1(); 

    // Do the rest 
    ... 
} 

所以我想我不明白你的問題。


基於更新後的問題,我會說,Assembly1.ClassA應該是起轉線的一個resposible:

public class ClassA 
{ 
    private Socket socket; 
    private Thread thread; 

    public void Connect() 
    { 
     socket = new Socket(...); 
     socket.Connect(...); 

     thread = new Thread(DoWork); 
     thread.Start(); 
    } 

    public void Disconnect() 
    { 
     socket.Shutdown(SocketShutdown.Both); 
     socket.Close(); 

     thread.Join(); 
    } 

    private void DoWork() 
    { 
     try 
     { 
      while (true) 
      { 
       int received = socket.Receive(buffer, ...); 
       if (received == 0) 
       { 
        break; 
       } 
       // process buffer 
       ... 
      } 
     } 
     catch (SocketException) 
     { 
      ... 
     } 
    } 
} 
+0

如果我需要保持線程活着,該怎麼辦?換句話說,在代碼片段中,只需要幾行即可停止所有線程。之後,新的線程可能會持續一段時間,這肯定會阻止調用線程,對吧? – EDJ

+0

@Ed Gl:你可以擴展這幾條特殊線路嗎? 「鎖定」比信號更合適嗎? – dtb

+0

我將發佈修改以澄清... – EDJ

相關問題