我正在开发 Blazor Server Web 应用程序,但我对使用 .ConfigureAwait(false)
感到困惑。我知道我不应该在组件代码中使用它,但我不确定嵌套代码。例如:我正在调用异步方法来更新按钮单击时页面上的数据。此方法本身也调用异步方法向 API 发出请求。问题是 - 是否应该使用 ConfigureAwait(false)
调用此嵌套方法(API 请求)?
编辑: 添加代码以更清楚地演示:
此方法从按钮 OnClick
调用
protected async Task GridRefresh()
{
Models = null;
_errorMessage = null;
try
{
Models = await _dataService.GetDataAsync(Active);
}
catch (Exception ex)
{
_errorMessage = ex.Message.Split("Message:").Last();
}
}
此方法位于我使用依赖注入(inject)添加到我的组件的 DataService
类中
public async Task<IEnumerable<ItemViewModel>> GetDataAsync(int id)
{
var container = await ApiWrapper.getByIDAsync(id);
if(container == null)
throw new Exception($"Container with code {id} not found!");
return container.Items;
}
问题是:我应该在 GetDataAsync
方法中使用 ConfigureAwait
吗?
var container = await ApiWrapper.getByIDAsync(id).ConfigureAwait(false);
最佳答案
您应该像在桌面应用程序中那样做。
- 要更新 UI,您必须在其同步上下文中,因此您不应在更新时使用
ConfigureAwait(false)
用户界面。 - 在非 UI 代码中,无需返回到 UI 上下文,因此您可能应该使用
ConfigureAwait(false)
并让顶级代码决定是否需要返回到 UI 上下文。这样您就可以避免在 UI 线程/上下文繁忙时可能出现的死锁。 - 在库代码中,您应该使用
ConfigureAwait(false)
来避免强制上下文切换和可能的死锁
在小的、干净的组件(无论如何你应该构建的组件类型)中,如果你省略 ConfigureAwait(false)
应该不会有这么大的问题。
在库代码中,省略 ConfigureAwait(false)
可能很容易导致死锁,尤其是在调试期间。事实上,我想知道一些流行的本地存储包遇到的死锁是否是由一些错过的ConfigureAwait
调用
关于c# - 在嵌套异步方法中使用 ConfigureAwait,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64553991/