何时使用AsyncOperation和AsyncOperationManager

时间:2009-05-15 15:29:34

标签: .net asynchronous

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

不幸的是,我在找到一个只支持一个Async调用的类时根本找不到任何文章。

我见过的每个例子都假设一个方法调用将被多次调用,因此,应该将一个userState对象传递给 MethodName Async

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

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

链接也不错:)

由于

2 个答案:

答案 0 :(得分:11)

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

因此,我将得出结论,同步上下文是一个简单的类,它决定委托将被执行的线程。

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

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

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

基本上,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();
  }
  ....
}

答案 1 :(得分:3)

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