异步死锁问题
Async deadlocks issues
我的代码在使用 await client.GetAsync(url)
和 await SendParkInfoRequest(parkRegionId)
时陷入死锁。如果我使用 ConfigureAwait(false)
.
它工作正常
下面是我的代码。
public virtual async Task<ParkingInfo> SendParkInfoRequest(string id)
{
using (var client = Helper.GetHttpClient())
{
//
var url = RequestUri + id;
var data = await client.GetAsync(url).ConfigureAwait(false);
string result = await data.Content.ReadAsStringAsync();
//
}
}
}
public async Task<AvailableSpotsResponse> GetAvailableSpots(string parkRegionId)
{
//
var data = await SendParkInfoRequest(parkRegionId).ConfigureAwait(false);
//
}
我的代码有没有哪里做错了。 Helper.GetHttpClient()
正在设置 HttpClient
。是不是这一行造成的死锁using (var client = Helper.GetHttpClient())
。
如有任何建议或帮助,我们将不胜感激。
提前致谢。
这种情况与Stephen Cleary 在其博客中提供的示例几乎完全相同:https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html。我强烈建议阅读并理解它,因为这是一个常见问题。
现在,即使没有 ConfigureAwait(false),您显示的代码也不会自行死锁。我的猜测是,在链的上游某处,您阻塞了异步代码,这导致了死锁。斯蒂芬在他的文章中概述了这个问题的两个解决方案:
- 在您的“库”异步方法中,尽可能使用 ConfigureAwait(false)。
- 不要阻塞任务;一直使用异步。
其中任何一个都可以防止死锁,但最好同时使用两者。
我的代码在使用 await client.GetAsync(url)
和 await SendParkInfoRequest(parkRegionId)
时陷入死锁。如果我使用 ConfigureAwait(false)
.
下面是我的代码。
public virtual async Task<ParkingInfo> SendParkInfoRequest(string id)
{
using (var client = Helper.GetHttpClient())
{
//
var url = RequestUri + id;
var data = await client.GetAsync(url).ConfigureAwait(false);
string result = await data.Content.ReadAsStringAsync();
//
}
}
}
public async Task<AvailableSpotsResponse> GetAvailableSpots(string parkRegionId)
{
//
var data = await SendParkInfoRequest(parkRegionId).ConfigureAwait(false);
//
}
我的代码有没有哪里做错了。 Helper.GetHttpClient()
正在设置 HttpClient
。是不是这一行造成的死锁using (var client = Helper.GetHttpClient())
。
如有任何建议或帮助,我们将不胜感激。
提前致谢。
这种情况与Stephen Cleary 在其博客中提供的示例几乎完全相同:https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html。我强烈建议阅读并理解它,因为这是一个常见问题。
现在,即使没有 ConfigureAwait(false),您显示的代码也不会自行死锁。我的猜测是,在链的上游某处,您阻塞了异步代码,这导致了死锁。斯蒂芬在他的文章中概述了这个问题的两个解决方案:
- 在您的“库”异步方法中,尽可能使用 ConfigureAwait(false)。
- 不要阻塞任务;一直使用异步。
其中任何一个都可以防止死锁,但最好同时使用两者。