Ioa*_*ana 4 c# client asynchronous blazor
我试图在 cs 类中调用异步方法,但页面冻结了。调试时,一切似乎都运行良好,直到上await thing.wait.WaitAsync();线。在该行之后,没有其他断点被击中(我周围有一堆断点,包括下一行上的一个),页面看起来像在继续加载,并且没有弹出错误/异常消息。
ApiClient_Test.razor
@if (myResult == null)
{
<p><em>Loading...</em></p>
}
else
{
<p>@myResult</p>
}
@code{
private string myResult;
protected override async Task OnInitializedAsync()
{
var test = new ApiClient_BlazorTest.ApiClientBlazorTests.ApiClient_TestAsync();
myResult = test.MyMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
ApiClientTest.cs
namespace ApiClient_BlazorTest.ApiClientBlazorTests
{
public class ApiClient_TestAsync : Controller
{
public string MyMethod()
{
var a = MyAsyncMethod();
a.Wait();
return a.Result;
}
public async Task<string> MyAsyncMethod()
{
var thing = new athing();
// start a thing that takes 6 seconds
thing.dothings();
// await the thing
await thing.wait.WaitAsync();
return "ok";
}
private class athing
{
public SemaphoreSlim wait { get; set; } = new SemaphoreSlim(1);
public string dothings()
{
wait.Wait();
Task.Run(() => { Thread.Sleep(6000); wait.Release(); });
return "";
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我在控制台应用程序上运行了相同的代码。那里一切都工作得很好。
有人在 blazor 和异步函数中见过类似的东西吗?
Blazor 渲染有一个SynchronizationContext,因此阻塞异步代码可能会导致死锁。
最好的解决方案是删除所有阻塞调用 - 即使用orawait代替:Wait()Result
public async Task<string> MyMethodAsync() // was `public string MyMethod()`
{
var a = MyAsyncMethod();
// await a; // was `a.Wait();`
return await a; // was `return a.Result;`
}
Run Code Online (Sandbox Code Playgroud)
我在控制台应用程序上运行了相同的代码。那里一切都工作得很好。
控制台应用程序没有SynchronizationContext,因此在该环境中不会发生这种死锁。