【发布时间】:2021-01-18 19:31:07
【问题描述】:
我有一个非常大的同步 Web 应用程序,它可以从异步调用中显着受益,但重构它以实现这一点需要大量工作。
在应用程序中有一个特定的点,其中进行了 2 次昂贵的远程调用,并且能够同时触发这两个调用将大大提高性能。显然流程是同步的,所以我使用Task.Run来实现异步调用:
private void RemoteCalls()
{
var task1 = Task.Run(async() => await DoExpensiveThing());
var task2 = Task.Run(async () => await DoAnotherExpensiveThing());
Task.WhenAll(task1, task2);
}
private async Task DoExpensiveThing()
{
await //some expensive call
}
private async Task DoAnotherExpensiveThing()
{
await //another expensive call
}
这成功实现了我所追求的,两个昂贵调用的工作同时执行并等待两者完成。
我的问题是,这样做有什么明显的缺点吗?我有一种(模糊的)感觉 async 真的被设计用于从上到下一直异步的应用程序。由于使用 Task.Run,在升级应用程序之前,我会因为使用上述内容而受苦吗?
【问题讨论】:
-
因为你没有使用
await和Task.WhenAll(task1, task2);你的程序会有问题。如果您需要在同步上下文中运行async代码,您仍然需要await最终结果 - 您可以使用线程池和经典同步原语(如ManualResetEvent)和“非阻塞”轮询循环以确保安全。 -
首先,异步和并发是不同的东西;听起来你真的很追求并发。请注意,
Task.WhenAll可能不是您真正想要的,因为它 返回一个必须等待的任务 - 但除非您处于异步上下文中,否则您不能等待,这意味着你实际上需要阻止 (Wait()),这是一个非常糟糕的主意。 -
@FBryant87 不幸的是,事情从来没有这么简单。幸运的是,ASP.NET WebForms 有它自己的“后台工作者”功能 (
hostingenvironment.queuebackgroundworkitem),您应该使用它。 -
@PeterCsala 因为这要求父方法也是
asyncOP 说他们不能这样做。
标签: c# .net asynchronous