【发布时间】:2021-10-04 13:11:40
【问题描述】:
我试图理解GetAwaiter().GetResult() 之间的概念。我知道如果可能的话不应该使用它,但在这种情况下我不能使用 async/await,所以我必须在同步问题中从异步函数中获取结果。
让我们考虑这个简单的 Blazor 服务器应用:
@page "/"
<button @onclick="GetAwaiterGetResultOnTask">Task GetAwaiter().GetResult()</button>
<button @onclick="GetAwaiterGetResultOnFunction">Function GetAwaiter().GetResult()</button>
<p>@_message</p>
@code {
private string _message;
private async Task<string> AsyncFunction(string message)
{
await Task.Delay(500);
return message;
}
private void GetAwaiterGetResultOnTask()
{
_message = Task.Run(() => AsyncFunction("Message from GetAwaiterGetResultOnTask")).GetAwaiter().GetResult();
}
private void GetAwaiterGetResultOnFunction()
{
_message = AsyncFunction("Message from GetAwaiterGetResultOnFunction").GetAwaiter().GetResult();
}
}
调用函数GetAwaiterGetResultOnFunction会导致死锁。但是,当我打电话给GetAwaiterGetResultOnTask 时,它没有。
这些函数之间的主要区别是什么?为什么在 Task.Run 上调用它不会导致死锁?
【问题讨论】:
-
因为
GetAwaiterGetResultOnFunction运行on your thread,而GetAwaiterGetResultOnTask运行在另一个上。 -
顺便说一句,这两个电话都很糟糕。改为使方法异步。 Blazor Server 广泛使用异步方法是有原因的。 每个 调用修改状态和 UI 是从服务器到浏览器的异步调用。通过阻止您的方式,您浪费了可用于服务其他请求的线程
-
I cannot use async/await in this case为什么?这是什么情况? Blazor,尤其是 Blazor Server,广泛使用async,以至于 not 使用异步比使用它更难。为什么不使用异步事件回调? event handling docs 表明:button @onclick="UpdateHeading"和private async Task UpdateHeading() -
这篇博文可能会解决这个问题:Don't Block on Async Code
-
ASP.NET Core 中尚不支持异步验证。这就是为什么我不能使用异步等待。
标签: c# asynchronous async-await deadlock