如何在收到异步函数的回调之前使线程休眠?
Posted
技术标签:
【中文标题】如何在收到异步函数的回调之前使线程休眠?【英文标题】:How to Sleep a thread until callback for asynchronous function is received? 【发布时间】:2011-09-12 11:11:05 【问题描述】:我有一个函数,只有在从异步函数接收到回调时才需要执行。
喜欢
我调用异步函数Stop()
,不久之后我调用异步函数Start()
。
收到停止回调之前的问题Start()
被调用,因此我遇到了问题。我也不能分开调用两个函数就像我不能这样做。:
public void SomeFunction()
Stop();
public void Stop_CallBack(eventargs e)
Start();
我必须这样做:
public void SomeFunction()
Stop();
//Do something;
Start();
但在我收到 Stop 回调之前,我的 start() 函数被执行,从而给我带来了问题。
谁能帮我解决这个问题。
【问题讨论】:
【参考方案1】:这是您想要使用等待句柄的时候。下面是一个简短的代码示例来展示一种方法:
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();
【讨论】:
你能解释一下为什么需要Stop_Callback
吗?为什么不在任务中直接调用stopWaitHandle.Set();
呢?
@Daniel:我不需要它;但问题指出 "[...] 仅在收到回调时才需要执行的函数 [...]" 并且 OP 已经在给定的代码示例中建议了这样的回调。我倾向于尽可能少地重构 OP 代码。例如,回调可能是从无权访问等待句柄的第 3 方代码调用的。
我无法调用 Stop_callback。这是我从其他应用程序收到的回调。
@Sumit:我的示例中的Task
仅用于拥有一个完全工作的示例。如果我理解正确,您在调用异步库方法时将Stop_Callback
作为参数传递,完成后将调用该方法?如果是这样,我的示例仍然有效,只是您将调用该异步方法而不是执行任务。【参考方案2】:
由于这些看起来像成员函数,您可以添加一个事件成员变量(ManualResetEvent
或 AutoResetEvent
。然后在 Stop()
方法中将事件设置为已发出信号。在调用 Stop( ) 和 Start() 你等待事件。
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
【讨论】:
我已经尝试过 AutoResetEvent 和 ManualRestEvent,但没有成功 如果您使用 ManualResetEvent,那么您必须在 WaitOne 调用后重置它 (_stopped.Reset()
),否则它会保持在信号状态。
你的意思是它对自动和手动重置事件不起作用?您的代码没有在 WaitOne() 调用中阻塞?在那种情况下,您可以发布更多代码吗?如果你有一个调用 Stop 的函数,做某事然后调用 Start。只要事件在 Stop 中发出信号并且仅在开始时重置,那么您的代码将在 WaitOne 处阻塞,直到发出事件信号为止。
我的意思是我的代码在 WaitOne() 处被阻止,但它阻止了一切,我无法收到 Stop() 的回调,我的代码被无限期地阻止。你能告诉我可能是什么原因吗?
您应该将等待句柄的设置移动到回调函数中。我不确定您的代码的顺序。 (见@Fredrik 的回答)。 WaitOne() 将阻塞直到句柄发出信号(Set()
被调用)。以上是关于如何在收到异步函数的回调之前使线程休眠?的主要内容,如果未能解决你的问题,请参考以下文章