c# - 在嵌套异步方法中使用 ConfigureAwait

标签 c# async-await blazor

我正在开发 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/

相关文章:

c# - 建立一个非顺序的数字列表(从一个大范围)

javascript - 如何使用 Express 从异步方法返回有效响应?

javascript - 如何从 TypeScript 发出 HTTP 请求

select - Blazor:在使用 @bind 时如何在 <select> 中使用 onchange 事件?

c# - 使具有相同值的对象之间的 HashSet<MyType> 不同

c# - HTML.DropDownListFor DropDownList

.net - WCF 3.5,异步桥接。包裹在 async-await 中

c# - 如何将参数传递给服务器端 Blazor 中的 razor 组件?

Blazor 3.1 嵌套的鼠标悬停事件

c# - 给定一个对象,它是一个枚举值数组,我如何在不知道枚举类型的情况下获得一个 Enum[]