使用顶级函数执行等待的嵌套异步调用
Nested Async calls with Top level function doing await
我有这种情况,想在走那条路之前检查是否可行。
我有一个 webApi 项目,有一个 delegateHandler 在 HttpContext.Current.Items 中添加了一些数据。在控制器中,我使用 configureawait(false) 进行的异步调用很少。在库 DLL 中相同。
整体代码如下所示......
在控制器中
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 中,classDBCalls
async void Method1Async()
{
await internalMethod1().configureawait(false)
}
async void Method2Async()
{
await internalMethod2().configureawait(false)
}
问题是当控制器功能恢复执行时,我会从 HttpContext.Current.Items 取回存储的数据吗?
When execution resumes back on controller function will I get stored data back from HttpContext.Current.Items
?
不,你不会。 ConfigureAwait(false)
恰好适用于您 不需要 恢复之前上下文的情况。但是要访问 HttpContext.Current
,您需要它。
你应该做的是在 "library" 代码中使用 ConfigureAwait(false)
(如 InternalMethodN
和可能的 Method1Async
),这不依赖于上下文。但是在需要 return 到 ASP.NET 请求上下文的 "application" 代码中,不要使用 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);
}
请注意,我已将 MethodNAsync
从 async void
更改为 async Task
。你不应该使用 async void
方法,除非你必须这样做,你肯定不能 await
它们。
此外,我假设真正的 MethodNAsync
确实在做某事。如果它们只是委托给内部方法,您可以将它们简化为(使用 C# 6.0 表达式主体方法使它们更短):
Task Method1Async() => InternalMethod1();
Task Method2Async() => InternalMethod2();
我有这种情况,想在走那条路之前检查是否可行。
我有一个 webApi 项目,有一个 delegateHandler 在 HttpContext.Current.Items 中添加了一些数据。在控制器中,我使用 configureawait(false) 进行的异步调用很少。在库 DLL 中相同。
整体代码如下所示......
在控制器中
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 中,classDBCalls
async void Method1Async()
{
await internalMethod1().configureawait(false)
}
async void Method2Async()
{
await internalMethod2().configureawait(false)
}
问题是当控制器功能恢复执行时,我会从 HttpContext.Current.Items 取回存储的数据吗?
When execution resumes back on controller function will I get stored data back from
HttpContext.Current.Items
?
不,你不会。 ConfigureAwait(false)
恰好适用于您 不需要 恢复之前上下文的情况。但是要访问 HttpContext.Current
,您需要它。
你应该做的是在 "library" 代码中使用 ConfigureAwait(false)
(如 InternalMethodN
和可能的 Method1Async
),这不依赖于上下文。但是在需要 return 到 ASP.NET 请求上下文的 "application" 代码中,不要使用 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);
}
请注意,我已将 MethodNAsync
从 async void
更改为 async Task
。你不应该使用 async void
方法,除非你必须这样做,你肯定不能 await
它们。
此外,我假设真正的 MethodNAsync
确实在做某事。如果它们只是委托给内部方法,您可以将它们简化为(使用 C# 6.0 表达式主体方法使它们更短):
Task Method1Async() => InternalMethod1();
Task Method2Async() => InternalMethod2();