2011-06-10 26 views
6

我有一个函数,只有当从异步函数收到回调时才需要执行。如何休眠线程,直到收到异步函数的回调?

我叫异步函数Stop()不久后,我调用异步函数Start()

发送停止回调前的问题Start()被调用,因此我得到的问题。

public void SomeFunction() 
{ 

    Stop(); 
    //Do something; 

    Start(); 
} 

但在此之前,我收到停止再打我的start()函数:也像我不能做到这一点:

public void SomeFunction() 
{ 
    Stop(); 
} 

public void Stop_CallBack(eventargs e) 
{ 
    Start(); 
} 

我必须这么做,我不能调用分开的两个功能被执行从而给我造成问题。

任何人都可以帮我解决这个问题。

回答

18

这是当你想要使用等待句柄。下面是一个简短的代码示例显示一个方法:

class AsyncDemo 
{ 
    AutoResetEvent stopWaitHandle = new AutoResetEvent(false); 
    public void SomeFunction() 
    {  
     Stop(); 
     stopWaitHandle.WaitOne(); // wait for callback  
     Start(); 
    } 
    private void Start() 
    { 
     // do something 
    } 
    private void Stop() 
    { 
     // This task simulates an asynchronous call that will invoke 
     // Stop_Callback upon completion. In real code you will probably 
     // have something like this instead: 
     // 
     //  someObject.DoSomethingAsync("input", Stop_Callback); 
     // 
     new Task(() => 
      { 
       Thread.Sleep(500); 
       Stop_Callback(); // invoke the callback 
      }).Start(); 
    } 

    private void Stop_Callback() 
    { 
     // signal the wait handle 
     stopWaitHandle.Set(); 
    } 

} 
+1

你能解释为什么你需要'Stop_Callback'吗?为什么不直接在任务中调用'stopWaitHandle.Set();'? – 2011-06-10 12:20:38

+1

@Daniel:*我*不需要它;但问题状态*“[...]只有在收到回调时才需要执行的函数[...]”*,并且OP已经在给定的代码示例中建议了这种回调。我倾向于尽可能少地重构OP代码。这可能是回调从第三方代码调用,例如无法访问等待句柄。 – 2011-06-10 12:23:34

+0

我无法调用Stop_callback。这是我从其他应用程序收到的回拨。 – Sumit 2011-06-10 12:26:31

2

由于这些像部件的功能,可以添加一个事件成员变量(或者是ManualResetEventAutoResetEvent。然后在Stop()方法你的事件设置为用信号通知。在调用之间停止()和启动()你等待事件

private AutoResetEvent _stopped = new AutoResetEvent(false); 

public void SomeFunction() 
{ 
    Stop(); 
    _stopped.WaitOne(); 
    Start(); 
} 

在停止功能,你会做

private void Stop() 
{ 
    try 
    { 
     // Your code that does something to stop 
    } 
    finally 
    { 
     _stopped.Set(); // This signals the event 
    } 
} 

如果使用ManualResetEvent -

private ManualResetEvent _stopped = new ManualResetEvent(false); 

public void SomeFunction() 
{ 
    Stop(); 
    _stopped.WaitOne(); 
    Start(); 
} 

private void Stop() 
{ 
    try 
    { 
     // Your code that does something to stop 
    } 
    finally 
    { 
     _stopped.Set(); // This signals the event 
    } 
} 

private void Start() 
{ 
    _stopped.Reset(); 

    // Your other start code here 
} 
+0

我已经用的AutoResetEvent和ManualRestEvent尝试和它没有工作 – Sumit 2011-06-10 12:28:49

+0

如果您使用的ManualResetEvent,那么你必须将其复位('_stopped.Reset()')在WaitOne调用之后,否则它会保持信号状态。 – pstrjds 2011-06-10 12:32:07

+0

你是什么意思,它不适用于自动和手动重置事件?您的代码在WaitOne()调用中没有阻塞?在这种情况下,你可以发布更多的代码?如果您有一个调用Stop的函数,则执行一些操作然后调用Start。只要事件在停止中被发信号并且只在开始时重置,那么代码将在WaitOne上阻塞,直到事件发出信号。 – pstrjds 2011-06-10 19:28:32