2011-07-22 20 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

相关问题