![](/img/trans.png)
[英]How to return a list of objects in ASP.NET Web API async controller method
[英]ASP.NET Web API async controller method and deadlock
请帮助我了解为什么此代码会导致死锁? 我有一个asp.net Web API应用程序,我试图使某些控制器方法异步。
[HttpPost]
[Authentication]
public async Task<SomeDTO> PostSomething([FromBody] SomeDTO someDTO)
{
return await _service.DoSomething(someDTO);
}
这就是被调用的服务方法的外观:
public async Task<SomeDTO> DoSomething(SomeDTO someDTO)
{
...
var someTask = Task.Run(() =>
{
var entity = new SomeEntity(someDTO);
return _repository.Create(entity);
});
...
var result = await someTask;
...
}
还有一些全局处理程序,可将对控制台的响应打印出来。
public class AppGlobalHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var resp = base.SendAsync(request, cancellationToken);
Debug.WriteLine($"Response:{request.RequestUri}{Environment.NewLine}{resp?.ConfigureAwait(false).GetAwaiter().GetResult()?.Content?.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult()}");
return resp;
}
}
看起来像ConfigureAwait(false).GetAwaiter()。GetResult()阻止了调用者线程,但是我认为ConfigureAwait(false)应该避免这种情况,不是吗?
ConfigureAwait(false)在这里不能为您提供帮助,因为它必须一直放在调用堆栈中(请参阅此处 ),而不是在您同步等待的地方,即它取决于base.SendAsync的实现。 如果它在当前线程上获得了锁定,则为时已晚。 毕竟,也不建议在ASP.net管道中继续在其他线程上响应(请参阅此处的讨论并在 此处发布)。
最后,在异步上下文中同步等待始终是一个高风险的想法。 如果您需要阅读内容,为什么不那样做:
public class AppGlobalHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var resp = await base.SendAsync(request, cancellationToken);
var content = resp?.Content != null
? (await resp.Content.ReadAsStringAsync())
: string.Empty;
Debug.WriteLine($"Response:{request.RequestUri}{Environment.NewLine}{content}");
return resp;
}
}
我认为您忽略了Task.Run()方法中的async关键字。
public async Task<SomeDTO> DoSomething(SomeDTO someDTO)
{
var someTask = Task.Run( async () => //simply add this for async run
{
var entity = new SomeEntity(someDTO);
return _repository.Create(entity);
});
var result = await someTask;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.