我有这种情况,想在走那条路线之前检查是否可行。

我有一个 webApi 项目,有一个 delegateHandler,它在 HttpContext.Current.Items 中添加了一些数据。在 Controller 中,我使用 configureawait(false) 执行的异步调用很少。在库 DLL 中相同。

整体代码看起来像这样......

在 Controller 中

public async Task<Entity> func()
{

HttpContext.Current.Items.Add(key, value);

await DBCalls.Method1Async().configureawait(false);
await DBCalls.Method2Async().configureawait(false);

var data = HttpContext.Current.Items[key];

// rest of the method
}

在 DLL 中,类 DBCalls
async void Method1Async()
{
   await internalMethod1().configureawait(false)
}
async void Method2Async()
{
   await internalMethod2().configureawait(false)
}

问题是当执行恢复到 Controller 功能时,我会从 HttpContext.Current.Items 取回存储的数据吗?

最佳答案



不,你不会。 ConfigureAwait(false) 完全适用于您不需要在先前的上下文中恢复的情况。但是要访问 HttpContext.Current ,您需要它。

您应该做的是在“库”代码(如 ConfigureAwait(false) 和可能的 InternalMethodN )中使用 Method1Async ,这不依赖于上下文。但是在需要返回 ASP.NET 请求上下文的“应用程序”代码中,不要使用 ConfigureAwait()

所以,你的代码应该是这样的:

public async Task<Entity> Func()
{
    HttpContext.Current.Items.Add(key, value);

    await DBCalls.Method1Async();
    await DBCalls.Method2Async();

    var data = HttpContext.Current.Items[key];

    // rest of the method
}

async Task Method1Async()
{
   await InternalMethod1().ConfigureAwait(false);
}

async Task Method2Async()
{
   await InternalMethod2().ConfigureAwait(false);
}

请注意,我已将 MethodNAsyncasync void 更改为 async Task 。您不应该使用 async void 方法,除非您必须这样做,而且您肯定无法对它们进行 await

另外,我假设真正的 MethodNAsync 实际上做了一些事情。如果它们只是委托(delegate)给内部方法,您可以将它们简化为(使用 C# 6.0 表达式体方法使它们更短):
Task Method1Async() => InternalMethod1();

Task Method2Async() => InternalMethod2();

关于c# - 具有等待的顶级函数的嵌套异步调用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39533710/

10-11 20:23