何时使用AsyncOperation和AsyncOperationManager

Vin*_*cio 4 .net asynchronous

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

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

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

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

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

链接也不错:)

谢谢

nig*_*der 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. */
  ...
}
Run Code Online (Sandbox Code Playgroud)

当操作完成时,使用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();
  }
  ....
}
Run Code Online (Sandbox Code Playgroud)