【发布时间】:2020-03-17 16:19:29
【问题描述】:
我们有一个 async/await 方法 GetLoanDataAsync,它通过实体框架调用存储过程,该实体框架由同步方法 GetData 调用。
GetLoanData 需要大量时间来执行,这可能是我们写成 async/await 的原因,它可以被多个地方使用。
我知道我们不应该混合使用异步和同步调用,但是假设我们有这种情况并且我们正在使用 Task.Run() 从同步方法 GetLoanDataAsync 调用异步方法 GetLoanDataAsync 我理解该方法 - @ 987654328@ 将在后台线程上运行。
我的问题是,如果我们有一个同步版本的异步方法 GetLoanDataAsync 并使用 Task.Run() 从 GetData 调用,那么在这种情况下会有什么不同?
提供有关该问题的更多详细信息-
我们有返回类型不是任务的 ASP.NET REST Web API。这是从角度应用程序调用的。这个 api 有几个称为 GetData() 的方法,我们在其中等待来自GetLoanDataAsync 的结果。据我了解,GetLoanDataAsync 将在后台线程中被调用,并且能够执行GetUserDetails(),一旦完成,它将返回执行GetLoanDataAsync 的结果。
代码-
public List<int> GetData(int id)
{
// Calls GetLoanDataAsync
var result = Task.Run(()=> GetLoanDataAsync(id));
// calls couple other sync methods
GetUserDetails();
return result.GetAwaiter().GetResult();
}
GetLoanDataAsync().Result 将导致死锁,这是较早的问题。为了解决这个问题,我们暂时尝试使用 Task.Run,直到我们将整个 api 设为异步。
【问题讨论】:
-
你如何处理Task.Run()的结果?你等待任务完成吗?如果是,那么这与首先使用同步版本并没有什么不同。
-
这是什么应用?网络?窗体?服务?
-
记住异步 != 并行。异步意味着线程在等待时被释放。并行意味着同时发生两件或多件事情(在不同的线程上)。
Task.Run将把它放在不同的线程上。由于它是一个异步方法,waiting happens nowhere. -
查看实际代码会有所帮助。
GetData是什么样的?它是怎么称呼的?它是什么类型的应用程序(桌面、Web 等)? -
如果这是在 Web 上下文中,这是个坏主意,因为 ASP.NET 的线程池有限,
Task.Run()将占用其中一个宝贵的线程。如果数据库调用是真正异步的,并且您是从同步/阻塞线程调用它,那么最好的选择是说var result = GetLoanDataAsync().Result。
标签: c# asynchronous async-await task