c# - Task.Factory.StartNew 与 Task.Factory.FromAsync

标签 c# .net asynchronous task-parallel-library

假设我们有一个 I/O 绑定(bind)方法(例如进行数据库调用的方法)。此方法既可以同步运行,也可以异步运行。也就是说,

  1. 同步:

    IOMethod()
    
  2. 异步:

    BeginIOMethod()
    EndIOMethod()
    

那么当我们以如下所示的不同方式执行该方法时,在资源利用率方面的性能差异是什么?

  1. var task = Task.Factory.StartNew(() => { IOMethod(); });
    task.Wait();
    
  2. var task = Task.Factory.FromAsync(BeginIOMethod, EndIOMethod, ... );
    task.Wait();
    

最佳答案

var task = Task.Factory.StartNew(() => { IOMethod(); });
task.Wait();

这将在 IOMethod() 执行时阻塞线程池线程,并且还会因为 Wait() 而阻塞当前线程。总阻塞线程:2.


var task = Task.Factory.FromAsync(BeginIOMethod, EndIOMethod, ... );
task.Wait();

这将(很可能)在不使用线程的情况下异步执行操作,但由于 Wait(),它会阻塞当前线程。总阻塞线程:1.


IOMethod();

这将在 IOMethod() 执行时阻塞当前线程。总阻塞线程:1.

如果您需要阻塞当前线程,或者如果阻塞对您来说没问题,那么您应该使用它,因为尝试使用 TPL 实际上不会给您任何东西。


var task = Task.Factory.FromAsync(BeginIOMethod, EndIOMethod, ... );
await task;

这将在不使用线程的情况下异步执行操作,并且还将等待操作异步完成,感谢 await。总阻塞线程:0。

如果您想利用异步并且可以使用 C# 5.0,那么您应该使用它。


var task = Task.Factory.FromAsync(BeginIOMethod, EndIOMethod, ... );
task.ContinueWith(() => /* rest of the method here */);

这将在不使用线程的情况下异步执行操作,并且还将等待操作异步完成,这要归功于 ContinueWith()。总阻塞线程:0。

如果你想利用异步并且你不能使用 C# 5.0,那么你应该使用它。

关于c# - Task.Factory.StartNew 与 Task.Factory.FromAsync,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17432306/

相关文章:

c# - 为什么延迟任务无法完全执行或阻塞 UI?

c# - ASP.NET 将反斜杠规范化为正斜杠

javascript - 客户端文本宽度的服务器端计算

c# - 一个页面只能有一个服务器端表单标签。 ASP.NET 中的表单错误

c# - LINQ 不会用 float 对组求和吗?属性(property)

jsf - 如何在@Asynchronous 方法中正确使用CDI?

c# - 数据绑定(bind)期间不绑定(bind)继承的属性

c# - 如何在 WP7 上以分钟为单位获取时区偏移量?

c# - .NET 正则表达式在带有所有格量词的可选文本之间匹配数字不起作用

javascript - Node.js - 解析 XML 时方法返回 UNDEFINED