c# - 订阅者方法与事件

标签 c# .net 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> 可以提供适当的重载,这对事件来说是不可能的:如果你有一个事件 EventHandler Finished in Task,你所能做的就是创建另一个事件,比如说,事件 EventHandler<TaskResultEventArgs>Task<TResult> 中完成,这不是很好),但我找不到对 CancellationToken.Register() 的相同解释。

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

public event EventHandler Finished;

// or

public IDisposable OnFinished(Action continuation)

非常感谢!

最佳答案

我想使用订阅者方法的一个优点是您可以轻松指定将在其上执行委托(delegate)的线程。参见 this overload的 CancellationToken.Register()。

更新:好吧,实际上你可以指定你的委托(delegate)将被发布到的同步上下文。

您对趋势的看法是正确的。 This article在 MSDN 杂志中声明如下:

New components shouldn’t use the event-based asynchronous pattern. The Visual Studio asynchronous Community Technology Preview (CTP) includes a document describing the task-based asynchronous pattern, in which components return Task and Task objects instead of raising events through SynchronizationContext. Task-based APIs are the future of asynchronous programming in .NET.

还有 document文章指的是说

Initiation and completion of an asynchronous operation in the TAP are represented by a single method, and thus there is only one method to name. This is in contrast to the IAsyncResult pattern, or APM pattern, where BeginMethodName and EndMethodName methods are required, and in contrast to the event-based asynchronous pattern, or EAP, where a MethodNameAsync is required in addition to one or more events, event handler delegate types, and EventArg-derived types.

确实,关注一件事情而不是很多事情是件好事。但这更多是 TAP 相对于 EAP 的优势,而不是订阅者方法的优势。

关于c# - 订阅者方法与事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6356329/

相关文章:

c# - 如何编写自己的基于XmlService 的ORM?

c# - MVVM 共享属性

c# - 内存中烧录System.String

c# - Wix 构建错误

c# - 连接列在数据表中添加数据

c# - UI 自动化是否有任何依赖项?

c# - 有没有办法防止 WPF 窗口中的 WinForms 控件被取消样式化?

java - JAX-WS 线程安全

c# - 如何确保 Task.Delay 更准确?

java - 访问匿名内部类中封闭范围的成员变量