订阅者方法与事件

Shd*_*dNx 6 .net c# multithreading .net-4.0 thread-safety

我注意到.NET 4.0中的一种新趋势,特别是在潜在的多线程场景中,它避免了事件,而是提供了订阅者方法.

例如,System.Threading.Tasks.TaskTask<TResult>使用ContinueWith()方法而不是Completed或Finished事件.另一个例子是System.Threading.CancellationToken:它有一个Register()方法而不是CancellationRequested事件.

虽然Task.ContinueWith()是合乎逻辑的,因为它允许简单的任务链接(对于事件不会那么优雅),并且它也允许Task<TResult>继承Task(因为这样,Task<TResult>可以提供适当的重载,这对于一个不可能event:如果你有一个事件EventHandler在Task中完成,你所能做的就是创建另一个事件,比如,事件已EventHandler<TaskResultEventArgs>完成Task<TResult>,这不是很好),但我找不到相同的CancellationToken.Register()解释.

那么,类似场景中事件的缺点是什么?我也应该遵循这种模式吗?澄清一下,我应该选择以下哪一项?我什么时候应该更喜欢另一个?

public event EventHandler Finished;

// or

public IDisposable OnFinished(Action continuation)
Run Code Online (Sandbox Code Playgroud)

非常感谢你!

Geb*_*ebb 2

我想使用订阅者方法的优点之一是您能够轻松指定委托将在其上执行的线程。请参阅CancellationToken.Register() 的重载

\n\n

更新:嗯,实际上您可以指定您的委托将被发布到的同步上下文。

\n\n

你对这种趋势的看法是正确的。MSDN 杂志中的这篇文章指出了以下内容:

\n\n
\n

新组件不应\xe2\x80\x99 使用基于事件的异步模式。\n Visual Studio 异步社区\n 技术预览版(CTP) 包含一个\n 描述基于任务的\n 异步模式的文档,其中\n 组件返回任务和\n 任务对象,而不是\n 通过\n 引发事件\n同步上下文。基于任务的 API 是 .NET 中异步编程的未来。

\n
\n\n

文章引用的文件说

\n\n
\n

TAP 中异步操作的启动和完成由单个方法表示,因此只有一个方法可命名。这与 IAsyncResult 模式或 APM 模式相反, \n 其中需要 BeginMethodName 和\n EndMethodName 方法,\n 与基于事件的\n 异步模式或 EAP 不同,其中\n 除了一个或多个事件之外,还需要\n MethodNameAsync、event\n处理程序委托类型和\n EventArg 派生类型。

\n
\n\n

事实上,处理一件事而不是多件事是件好事。但这更多的是TAP相对于EAP的优势,而不是订阅者方法的优势。

\n