今晚我花了很多时间阅读实现基于事件的异步模式
不幸的是,我在找到一个只支持一个Async调用的类时根本找不到任何文章。
我见过的每个例子都假设一个方法调用将被多次调用,因此,应该将一个userState对象传递给 MethodName Async
你会看到MS在本文的第三个要点中提到了这一点 http://msdn.microsoft.com/en-us/library/ms228974(VS.80).aspx在“同时执行操作”标题下。
但我很困惑。我是否应该使用AsyncOperation和AsyncOperationManager类来实现异步功能,其中方法一次只能被一个线程调用?
链接也不错:)
由于
答案 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