【问题标题】:Wait handle for callback等待回调句柄
【发布时间】:2017-08-23 08:27:03
【问题描述】:

为了从服务器异步获取数据,我使用getData.BeginInvoke(callback, null),其中getData 是获取数据的方法。 callback 对检索到的数据进行一些工作和通知。

在调用方法中,我读过的好习惯是使用WaitHandle 等待方法完成。我的问题是:WaitHandle 是否也等待回调完成?如果没有,怎么办?

代码:

Func<Data> getData = () => 
{
    //... 
};

AsyncCallback callback = (IAsyncResult ar) => 
{
    //... 
};

IAsyncResult result = getData.BeginInvoke(callback, null);

result.AsyncWaitHandle.WaitOne();

注意1:我必须使用framework 3.5,所以我不能使用async & await

注意2:我不认为这个问题与this post 重复。

【问题讨论】:

  • 实际上,您希望将异步调用设置为方法中的最后一个调用(如果在获取数据时不能同时执行其他任何操作)并在回调中继续您的流程。当异步方法返回时,回调将被调用。
  • 这可能会有所启发:docs.microsoft.com/en-us/dotnet/standard/… 在开始异步操作后立即阻塞通常没有多大意义。你也可以同步调用该函数。
  • 这取决于您将等待句柄设置为 true 的位置。查看 msdn 套接字示例:msdn.microsoft.com/en-us/library/bew39x2a(v=vs.100).aspx

标签: c# asynchronous callback


【解决方案1】:

你是对的,WaitOne 表示 BeginInvoke 的目标已经完成,但并不保证回调的完成。在这种情况下,您必须使用ManualResetEvent 才能自己手动处理:

    Func<Data> getData = () =>
    {
        //...
    };
    AsyncCallback callback = (IAsyncResult ar) =>
    {
        // do your thing...
        getData.EndInvoke(ar);
        waiter.Set();
    };

    ManualResetEvent waiter;

    void DoWork()
    {
        waiter = new ManualResetEvent(false);
        IAsyncResult result = getData.BeginInvoke(callback, null);
        waiter.WaitOne();
        //Callback has finished
    }

【讨论】:

  • 再次:在这里使用异步操作有什么意义,当您在启动后等待它完成?
  • @Fildor 很可能他做了一些他在中间没有表现出来的事情。他提供的代码是经过总结的,只是说明了他遇到的问题,因此我向他提供了他正在寻找的答案。
  • 很好的答案。谢谢@Hubbs。 +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-17
  • 1970-01-01
相关资源
最近更新 更多