Gab*_*Roy 3 .net c# azure async-await
在Web应用程序中使用KeyVault的示例代码中包含以下代码:
public static async Task<string> GetSecret(string secretId)
{
var secret = await keyVaultClient.GetSecretAsync(secretId);
return secret.Value;
}
Run Code Online (Sandbox Code Playgroud)
我已将KeyVaultAccessor示例中包含的对象合并到我的应用程序中以进行测试.该调用作为对我的一个web api控制器方法的查询的一部分执行:
var secret = KeyVaultAccessor.GetSecret("https://superSecretUri").Result;
Run Code Online (Sandbox Code Playgroud)
不幸的是,调用永远不会返回,查询将无限期挂起......
可能是什么原因,因为坦白说我不知道从哪里开始......?
Ste*_*ary 13
这是我在博客中完整描述的常见死锁问题.简而言之,该async方法尝试在await完成后返回到ASP.NET请求上下文,但该请求一次只允许一个线程,并且该上下文中已有一个线程(在调用时阻塞的线程Result).因此任务正在等待上下文自由,并且线程阻止上下文直到任务完成:死锁.
正确的解决方案是使用await而不是Result:
var secret = await KeyVaultAccessor.GetSecret("https://superSecretUri");
Run Code Online (Sandbox Code Playgroud)
小智 11
我使用以下代码来覆盖同步上下文:
var secret = Task.Run(async () => await KeyVaultAccessor.GetSecretAsync("https://superSecretUri")).Result;
Run Code Online (Sandbox Code Playgroud)
.Result如果您使用的是非异步方法,这仍然可以使用
不幸的是,该调用永远不会返回并且查询无限期挂起......
你遇到了一个经典的僵局。这就是为什么你不应该阻塞异步代码。在幕后,编译器生成一个状态机并捕获称为SynchronizationContext. 当您同步阻止调用线程时,尝试将延续发布回同一上下文会导致死锁。
不要使用同步阻塞.Result,而是让控制器异步并等待Task从返回的值GetSecret:
public async IHttpActionResult FooAsync()
{
var secret = await KeyVaultAccessor.GetSecretAsync("https://superSecretUri");
return Ok();
}
Run Code Online (Sandbox Code Playgroud)
旁注- 异步方法应遵循命名约定并以Async.
| 归档时间: |
|
| 查看次数: |
6785 次 |
| 最近记录: |