提问人:LeBigCat 提问时间:10/17/2023 最后编辑:Heretic MonkeyLeBigCat 更新时间:10/17/2023 访问量:116
使用 HttpClient 进行调试时出现死锁
Deadlock while debugging using HttpClient
问:
我必须使用 HttpClient(发送数百个请求)查询外部 Web 服务。 我使用 HttpClient 制作了一个经典的异步 await 循环,但在调试时,大约 5-10% 的时间 Visual Studio 会冻结,不确定它是否是死锁。取消令牌不起作用,我必须使用任务管理器终止进程。 使用命令提示符启动程序时,我仍然遇到 0 问题。
代码冻结在 上。有时只需 3 到 4 个 HTTP 请求即可。
目标服务是一家著名的酒店供应商(无法共享 ID),我将在最终版本中使用节流器。SendAsync
SemaphoreSlim
使用 .NET 5.0.18 (.NET 4.5) Visual Studio 2019 (16.11)Visual Studio 2019 (16.11)Visual Studio 2019 (16.11)Visual Studio 2019 (16.11)Visual Studio 2019 (16.11)
Visual Studio 2019 (
我阅读了这个 GitHub 问题并禁用了我的问题,但这并没有解决我的问题。System.Runtime.TieredCompilation
System.Runtime.ProfApi_RejitOnAttach
runtimeconfig.template.json
public class WebServiceCaller {
//wont be release atm
protected static readonly HttpClient clientSingleton = new HttpClient();
public async Task<string> CallerAynx(List<string> urls) {
CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(30000);
Stopwatch watchTime = new Stopwatch();
watchTime.Start();
string formattedDateTime = DateTime.Now.ToString("dddd, dd MMMM yyyy HH:mm:ss");
List<Task> taskList = new List<Task>();
//KO while debuging about 10% of the time after 2=> 6 http SendAsync call
urls.ForEach(url => {
taskList.Add(HttpClientToolsSendAsync(url, cts.Token));
});
await Task.WhenAll(taskList).ConfigureAwait(false);
//work when using a thread pool
await Task.Run(() => urls.ForEach(url => {
taskList.Add(HttpClientToolsSendAsync(url, cts.Token));
}));
await Task.WhenAll(taskList).ConfigureAwait(false);
watchTime.Stop();
Console.WriteLine($"Final ASYNC: {watchTime.Elapsed}");
return "OK";
}
private async Task<string> HttpClientToolsSendAsync(string url, CancellationToken cancellationToken) {
//wathever for the moment
string result = string.Empty;
try {
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
HttpRequestMessage request = new HttpRequestMessage()
{
RequestUri = new Uri(url),
Method = HttpMethod.Get,
};
//my ids
string clearIds = "Login:Password";
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Base64Encode(clearIds));
//deadlock - bug here
var response = await clientSingleton.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
if (response.IsSuccessStatusCode) {
result = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);;
}
else {
result = "KOHTTP";
}
}
catch (Exception ex) {
//fire or forget, we dont really want to manage exception
//wont be catch by tasks.when all
result = ex.Message;
}
return result;
}
private static string Base64Encode(string textToEncode) {
byte[] textAsBytes = Encoding.UTF8.GetBytes(textToEncode);
return Convert.ToBase64String(textAsBytes);
}
}
主课:
class Program
{
private static async Task Main(string[] args)
{
//i have a function generating my url here
List<string> urls = new List<string>();
WebServiceCaller caller = new WebServiceCaller();
//configure await added everywhere because this code could be used as a library later
await caller.CallerAynx(urls).ConfigureAwait(false);
Console.ReadLine();
}
}
答: 暂无答案
评论
HttpClient
HttpClientFactory
HttpClient
HttpClient
SendAsync