Kar*_*mar 170 c# task-parallel-library dotnet-httpclient
当有一个或两个任务时它可以正常工作但是当我们列出了多个任务时会抛出错误"任务被取消".

List<Task> allTasks = new List<Task>();
allTasks.Add(....);
allTasks.Add(....);
Task.WaitAll(allTasks.ToArray(), configuration.CancellationToken);
private static Task<T> HttpClientSendAsync<T>(string url, object data, HttpMethod method, string contentType, CancellationToken token)
{
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, url);
HttpClient httpClient = new HttpClient();
httpClient.Timeout = new TimeSpan(Constants.TimeOut);
if (data != null)
{
byte[] byteArray = Encoding.ASCII.GetBytes(Helper.ToJSON(data));
MemoryStream memoryStream = new MemoryStream(byteArray);
httpRequestMessage.Content = new StringContent(new StreamReader(memoryStream).ReadToEnd(), Encoding.UTF8, contentType);
}
return httpClient.SendAsync(httpRequestMessage).ContinueWith(task =>
{
var response = task.Result;
return response.Content.ReadAsStringAsync().ContinueWith(stringTask =>
{
var json = stringTask.Result;
return Helper.FromJSON<T>(json);
});
}).Unwrap();
}
Run Code Online (Sandbox Code Playgroud)
Tod*_*ier 245
有两种可能的原因TaskCanceledException会抛出:
Cancel()对CancellationTokenSource与任务完成之前取消令牌相关联.HttpClient.Timeout.我的猜测是暂停.(如果是明确的取消,你可能会想到这一点.)你可以通过检查异常来更加确定:
try
{
var response = task.Result;
}
catch (TaskCanceledException ex)
{
// Check ex.CancellationToken.IsCancellationRequested here.
// If false, it's pretty safe to assume it was a timeout.
}
Run Code Online (Sandbox Code Playgroud)
小智 17
var clientHttp = new HttpClient();
clientHttp.Timeout = TimeSpan.FromMinutes(30);
Run Code Online (Sandbox Code Playgroud)
以上是等待大请求的最佳方法。你有大约 30 分钟的困惑;这是随机时间,你可以给任何你想要的时间。
换句话说,如果他们在 30 分钟之前得到结果,请求将不会等待 30 分钟。30 分钟表示请求处理时间为 30 分钟。当我们发生错误“任务被取消”,或大数据请求要求时。
Car*_*lsh 12
将@JobaDiniz 的评论提升为答案:
HttpClient即使代码“看起来正确”,也不要做明显的事情并处置实例:
async Task<HttpResponseMessage> Method() {
using (var client = new HttpClient())
return client.GetAsync(request);
}
Run Code Online (Sandbox Code Playgroud)
处置该HttpClient实例可能会导致其他实例启动的后续 HTTP 请求HttpClient被取消!
C# 的新 RIAA 语法也会发生同样的情况;稍微不太明显:
async Task<HttpResponseMessage> Method() {
using var client = new HttpClient();
return client.GetAsync(request);
}
Run Code Online (Sandbox Code Playgroud)
相反,HttpClient接口有点粗糙,在 dotnet core 2.1+ 中使用它的正确方法是:
使用静态或单
HttpClient例实例PooledConnectionLifetime...
基本上,为您的应用程序或库缓存一个静态实例HttpClient,然后重用它:
static HttpClient client = new HttpClient();
async Task<HttpResponseMessage> Method() {
return client.GetAsync(request);
}
Run Code Online (Sandbox Code Playgroud)
(Async()请求方法都是线程安全的。)
但是,微软建议 您不要使用,不要直接使用 new HttpClient()!对于 dotnet core 和 .NET Framework,请使用IHttpClientFactory. 需要注意的是:文档IHttpClientFactory通常适用于 ASP.NET 应用程序,但可以在任何 CLI/GUI 应用程序中使用它。)
(对于 .NET Framework,“您可以将Microsoft.Extensions.Http NuGet 包添加到任何符合 .NET Standard 2.0 的项目中”——请参阅此答案。)
在我的 .net core 3.1 应用程序中,我遇到两个问题,其中内部原因是超时异常。1,一种是我收到聚合异常,其内部异常是超时异常2,另一种情况是任务取消异常
我的解决方案是
catch (Exception ex)
{
if (ex.InnerException is TimeoutException)
{
ex = ex.InnerException;
}
else if (ex is TaskCanceledException)
{
if ((ex as TaskCanceledException).CancellationToken == null || (ex as TaskCanceledException).CancellationToken.IsCancellationRequested == false)
{
ex = new TimeoutException("Timeout occurred");
}
}
Logger.Fatal(string.Format("Exception at calling {0} :{1}", url, ex.Message), ex);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
131330 次 |
| 最近记录: |