【问题标题】:Blocking until an event completes阻塞直到事件完成
【发布时间】:2010-12-04 03:14:23
【问题描述】:

如何在异步事件完成之前阻塞?

这是一种阻塞直到事件被调用的方法,方法是在事件处理程序中设置一个标志并轮询该标志:

private object DoAsynchronousCallSynchronously()
{
    int completed = 0;
    AsynchronousObject obj = new AsynchronousObject();
    obj.OnCompletedCallback += delegate { Interlocked.Increment(ref completed); };
    obj.StartWork();

    // Busy loop
    while (completed == 0)
        Thread.Sleep(50);

    // StartWork() has completed at this point.
    return obj.Result;
}

有没有办法在没有轮询的情况下做到这一点?

【问题讨论】:

    标签: c# events asynchronous iasyncresult


    【解决方案1】:
        private object DoAsynchronousCallSynchronously()
        {
            AutoResetEvent are = new AutoResetEvent(false);
            AsynchronousObject obj = new AsynchronousObject();    
            obj.OnCompletedCallback += delegate 
            {
                are.Set();
            };    
            obj.StartWork();    
    
            are.WaitOne();
            // StartWork() has completed at this point.    
            return obj.Result;
        }
    

    【讨论】:

      【解决方案2】:

      不使用异步操作?异步操作背后的重点不是阻塞调用线程。

      如果您想在操作完成之前阻塞调用线程,请使用同步操作。

      【讨论】:

      • 除非 API/Object 不公开同步调用(事实上我现在正在使用一个不公开的)。
      • 用最简单的话来说,你可能是对的,但是如果你想执行 X 次异步操作并阻塞调用者直到所有 X 都完成怎么办?如果这就是 OP 试图问的问题,我可能会改写这个问题,但是当我读到这个问题时,这是我跳出来的第一件事。
      • 如果 API 没有公开同步调用,我会认真看看为什么要在方法完成时阻塞调用线程。并不意味着它是错误的,但它绝对值得再看一遍。
      • @Justing:是的,它确实值得再看一遍,但肯定有 API 有这种行为。我认为 API 本身有点缺陷,但我无法选择它们的编写方式,我只需要使用它们。
      猜你喜欢
      • 2021-07-30
      • 2015-05-15
      • 2014-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-31
      相关资源
      最近更新 更多