假设我们有一个 I/O 绑定(bind)方法(例如进行数据库调用的方法)。此方法既可以同步运行,也可以异步运行。也就是说,
同步:
IOMethod()
异步:
BeginIOMethod() EndIOMethod()
那么当我们以如下所示的不同方式执行该方法时,在资源利用率方面的性能差异是什么?
-
var task = Task.Factory.StartNew(() => { IOMethod(); }); task.Wait();
-
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/