在遇到“公共”异步死锁并获得异步最佳实践的进一步理解之后,我尝试在ASP.NET中模拟这个问题,试图找出为什么我们以前从未遇到过这个问题。不同之处似乎在于,我们以前使用的是http客户端get异步方法,而这并没有引起任何问题。
public class DeadLockController : ApiController
{
/// <summary>
/// Does not result in deadlock - but why?
/// </summary>
[HttpGet]
public IHttpActionResult HttpDeadLock()
{
var client = new HttpClient();
return Ok( client.GetStringAsync( "https://www.google.com/" ).Result );
}
/// <summary>
/// Results in expected repeatable deadlock.
/// </summary>
[HttpGet]
public IHttpActionResult DeadLock()
{
var delayTask = DelayAsync().Result;
return Ok( delayTask );
}
/// <summary>
/// Does not result in deadlock.
/// </summary>
[HttpGet]
public async Task< IHttpActionResult > FixedDeadLock()
{
var delayTask = await DelayAsync();
return Ok( delayTask );
}
private async Task< int > DelayAsync()
{
await Task.Delay( 1000 );
return 0;
}
}因此,如果要调用api/DeadLock/DeadLock,就会遇到本文中描述的常见死锁。这是预期的/理解的。api/DeadLock/FixedDeadLock是解决这一问题的“正确”方法。
然而,调用 api/DeadLock/HttpDeadLock 并不会导致死锁,尽管它们在概念上是相同的,我也不知道为什么? HttpClient为什么没有遇到这个问题?从理论上讲,Httpclient在内部进行等待。
发布于 2015-12-16 17:28:10
api/死锁/HttpDeadLock不是死锁的原因是因为在该代码中,您没有等待任何任务。
相反,您是通过调用Task.Result来同步等待任务来阻塞线程。
在实现这种模式时,死锁通常会产生异步等待和Task.Wait/Task.Result组合的组合。
https://stackoverflow.com/questions/34317530
复制相似问题