代码之家  ›  专栏  ›  技术社区  ›  Razor

何时使用AsyncOperation和AsyncOperationManager

  •  4
  • Razor  · 技术社区  · 15 年前

    今晚我花了很多时间来阅读实现基于事件的异步模式

    不幸的是,我还没有找到任何关于只支持一个异步调用的类的文章。

    我看到的每个示例都假定一个方法调用将被多次调用,因此,应该将一个userstate对象传递到 方法名称 异步的

    你会看到微软在本文的第三个要点中提到了这一点。 http://msdn.microsoft.com/en-us/library/ms228974(VS.80).aspx 在“同时执行操作”标题下。

    但我很困惑。我是否应该使用AsyncOperation和AsyncOperationManager类来具有异步功能,其中一个方法一次只能由一个线程调用?

    链接也不错:)

    谢谢

    2 回复  |  直到 14 年前
        1
  •  3
  •   Charles Prakash Dasari    15 年前

    本文从codeproject清楚地解释了您问题的答案: http://www.codeproject.com/KB/cpp/SyncContextTutorial.aspx

        2
  •  11
  •   nightcoder    14 年前

    首先,我们需要说明什么是同步上下文。
    同步上下文是一个类,它决定应该执行哪些线程操作。
    主要同步上下文类-SynchronizationContext和WindowsFormsSynchronizationContext-只是简单的类,可以将操作委托给其他线程。
    synchronizationContext.post()方法只是从线程池(在内部使用thread pool.queueUserWorkItem(…)方法)将操作委托给一些线程。
    synchronizationContext.send()方法只在同一线程中执行委托。
    WindowsFormsSynchronizationContext最常用的用法如下:当您创建应用程序的主窗体时,WindowsFormsSynchronizationContext在内部为主GUI线程设置。稍后,此同步上下文用于在同一个主GUI线程上执行委托。

    所以,我要总结一下,同步上下文是一个简单的类,它决定委托将执行哪个线程。

    现在,让我们返回AsyncOperationManager类。
    当需要在某些同步上下文上执行操作时,可以使用AsyncOperationManager类。将在其上执行操作的同步COTNEXT可以是:

    1)如果线程定义了同步上下文,则调用AsyncOperationManager.CreateOperation()方法的同步上下文。

    2)如果当前线程尚未定义同步上下文,则为新的同步上下文(由基本同步上下文类的新实例表示)。如前所述,基同步上下文类的实例将在线程池中的某个线程上执行委托。

    基本上,AsyncOperationManager只是一个简单的助手类,它在内部使用AsyncOperation和SynchronizationContext类。

    现在,关于使用场景。
    例如,在主GUI线程中,您创建了一个类,该类使用基于事件的异步模式提供异步操作(即,它提供报告进度的事件)。
    您希望事件处理程序在同一个GUI线程中执行,这样您就可以使用事件处理程序中的GUI控件。
    在这种情况下,在OperationAsync方法中,您将创建一个AsyncOperation对象,并将其存储以供以后使用:

    public void OperationAsync(object arg1, object arg2, ...)
    {
      _asyncOperation = AsyncOperationManager.CreateOperation(null);
      /* _asyncOperation object now captured current synchronization 
         context, which is WindowsFormsSynchronizationContext if you 
         run this method from GUI thread. */
      ...
    }
    

    当操作完成时,使用asyncOperation.post()方法引发OperationCompleted事件。如果从应用程序的GUI线程运行AsyncOperationManager.CreateOperation()方法,则事件处理程序将在同一线程上执行,即在主GUI线程上执行:

    private void OnOperationCompleted(AsyncCompletedEventArgs e)
    {
      EventHandler<AsyncCompletedEventArgs> handler = OperationCompleted;
      if(handler != null)
      {
        _asyncOperation.Post(
          delegate
          {
            handler(this, e);
          },
          null);
    
        _asyncOperation.OperationCompleted();
      }
      ....
    }