gpt4 book ai didi

c# - HttpClientFactory 任务取消异常 : Unable to read data from the transport connection

转载 作者:行者123 更新时间:2023-12-02 11:19:05 24 4
gpt4 key购买 nike

我创建了一个简单的控制台应用程序,它使用 new ASP.NET Core 2.1 HttpClientFactory 从 archive.org 下载单个 (PDF) 文件。 .

对于该程序中使用的特定 URL,我总是得到一个 TaskCanceledException .如果您尝试运行此代码,您可能会遇到相同的异常。不过,它适用于 archive.org 上的其他 URL。当使用 wget 从完全相同的 URL ( wget https://archive.org/download/1952-03_IF/1952-03_IF.pdf --output-document=IF.pdf ) 下载文件时
下载成功。

但是,当我使用 HttpClient 执行此操作时我得到以下异常。

我可能做错了什么?

这是简单的代码:

using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using System.IO;
using System.Diagnostics;

namespace test2
{
public class Program
{
public static async Task Main(string[] args)
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddHttpClient("archive", c =>
{
c.BaseAddress = new Uri("https://archive.org/download/");
c.DefaultRequestHeaders.Add("Accept", "application/pdf");
})
.AddTypedClient<ArchiveClient>();

var services = serviceCollection.BuildServiceProvider();
var archive = services.GetRequiredService<ArchiveClient>();
await archive.Get();
}

private class ArchiveClient
{
public ArchiveClient(HttpClient httpClient)
{
HttpClient = httpClient;
}

public HttpClient HttpClient { get; }

public async Task Get()
{
var request = new HttpRequestMessage(HttpMethod.Get, "1952-03_IF/1952-03_IF.pdf");
var response = await HttpClient.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
using (Stream contentStream = await response.Content.ReadAsStreamAsync(),
fileStream = new FileStream("Worlds of IF 1952-03.pdf", FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
{
var totalRead = 0L;
var totalReads = 0L;
var buffer = new byte[8192];
var isMoreToRead = true;

do
{
var read = await contentStream.ReadAsync(buffer, 0, buffer.Length);
if (read == 0)
{
isMoreToRead = false;
}
else
{
await fileStream.WriteAsync(buffer, 0, read);

totalRead += read;
totalReads += 1;

if (totalReads % 2000 == 0)
{
Console.WriteLine(string.Format("bytes downloaded: {0:n0}", totalRead));
}
}
}
while (isMoreToRead);
}
}
}
}
}

这是我得到的完整异常(exception):
Unhandled Exception: System.Threading.Tasks.TaskCanceledException: The operation was canceled. 
---> System.IO.IOException: Unable to read data from the transport connection: Operation canceled.
---> System.Net.Sockets.SocketException: Operation canceled
--- End of inner exception stack trace ---
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error)
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.GetResult(Int16 token)
at System.Net.Security.SslStreamInternal.<FillBufferAsync>g__InternalFillBufferAsync|38_0[TReadAdapter](TReadAdapter adap, ValueTask`1 task, Int32 min, Int32 initial)
at System.Net.Security.SslStreamInternal.ReadAsyncInternal[TReadAdapter](TReadAdapter adapter, Memory`1 buffer)
at System.Net.Http.HttpConnection.FillAsync()
at System.Net.Http.HttpConnection.CopyToExactLengthAsync(Stream destination, UInt64 length, CancellationToken cancellationToken)
at System.Net.Http.HttpConnection.ContentLengthReadStream.CompleteCopyToAsync(Task copyTask, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.HttpConnection.ContentLengthReadStream.CompleteCopyToAsync(Task copyTask, CancellationToken cancellationToken)
at System.Net.Http.HttpConnection.HttpConnectionResponseContent.SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken)
at System.Net.Http.HttpContent.LoadIntoBufferAsyncCore(Task serializeToStreamTask, MemoryStream tempBuffer) at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at test2.Program.ArchiveClient.Get() in /Users/Foo/Temp/test3/Program.cs:line 42
at test2.Program.Main(String[] args) in /Users/Foo/Temp/test3/Program.cs:line 27
at test2.Program.<Main>(String[] args)

最佳答案

在您的情况下,大小似乎是问题所在。我会尝试的另一件事是通过

HttpCompletionOption.ResponseHeadersRead

在 SendAsync() 作为第二个参数。发生的情况是您的方法在读取标题后立即返回。响应不再缓冲在 MemoryStream 缓冲区中,而是直接从套接字读取。这意味着您可以在流式传输整个对象之前开始流式传输。性能方面它要快得多,在您的情况下,速度可能至关重要。

请记住处理响应消息,否则连接将不会被释放。

关于c# - HttpClientFactory 任务取消异常 : Unable to read data from the transport connection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49909170/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com