【发布时间】:2018-05-04 01:37:09
【问题描述】:
假设我有一个如下库,用于非基于 UI 的应用程序 (ASP.NET) 和基于 UI 的应用程序(WinForm 和 WPF)。不幸的是,我无法避免混合 IO 密集型工作和 CPU 密集型工作,但我让消费者通过 Task.Run 调用 DummyWorkAsync 或不基于他们的应用程序类型(非 UI 或基于 UI 的应用程序)。
class DummyService
{
public static async Task<int> DummyWorkAsync()
{
// Do some I/O first.
await Task.Delay(1000);
// Tons of work to do in here!
for (int i = 0; i != 10000000; ++i)
;
// Possibly some more I/O here.
await Task.Delay(1000);
// More work.
for (int i = 0; i != 10000000; ++i)
;
return 0;
}
}
这允许基于 UI 的消费者正确地使用Task.Run 来调用服务,而 ASP.NET 客户端将直接调用该方法,如下所示。
private async void MyButton_Click(object sender, EventArgs e)
{
await Task.Run(() => DummyService.DummyWorkAsync());
}
public class Home: Controller
{
public async Task<ActionResult> IndexAsync()
{
var result = await DummyService.DummyWorkAsync();
return View(result);
}
}
问题
我对基于 UI 的应用程序很感兴趣。如果我使用有什么区别
private async void MyButton_Click(object sender, EventArgs e)
{
await Task.Run(async () => await DummyService.DummyWorkAsync());
}
而不是
private async void MyButton_Click(object sender, EventArgs e)
{
await Task.Run(() => DummyService.DummyWorkAsync());
}
?
【问题讨论】:
-
第一个只有在
DummyWorkAsync在 UI 线程上完成后需要做某事时才有用,所以从技术上讲,它实际上是在等待它完成但同时不阻塞 UI 线程. -
@Clemens:因为“混合”
DummyWorkAsync中有一些 CPU 绑定的作品。对于这种混合异步方法,我们需要在基于 UI 的应用程序中使用Task.Run。 -
既然您的 IO 先行(我的意思是先等待 Task.Delay),为什么不直接添加 ConfigureAwait(false) 呢?然后你也可以从 UI 调用它,而不用包裹在 Task.Run 中。
标签: c# asp.net wpf lambda async-await