我有这个代码
using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
using (var reader = new BinaryReader(stream, Encoding.UTF8))
using (cancellationToken.Register(() =>
{
try { stream.Dispose(); }
catch { }
}))
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
var messageHeader = ReadMessageHeader(reader);
...
}
private static MessageHeader ReadMessageHeader(BinaryReader streamReader)
{
var messageHeader = new MessageHeader();
while (true)
{
var line = streamReader.ReadLine();
...
}
public static string ReadLine(this BinaryReader reader)
{
var result = new StringBuilder();
bool foundEndOfLine = false;
char ch;
while (!foundEndOfLine)
{
try
{
ch = reader.ReadChar();
...
}
据我了解,一段代码
using (cancellationToken.Register(() =>
{
try { stream.Dispose(); }
catch { }
}))
这样做正是为了使流崩溃并完成读取,因为ReadChar()
如果流未接收到数据,它可能处于等待状态。
这种方法的问题是抛出了 IOException。
如果平台是 NetFramework 4.8,则 InnerExseption SocketErrorCode 包含System.Net.Sockets.SocketError.Interrupted Не удается прочитать данные из транспортного соединения: Операция блокирования прервана вызовом WSACancelBlockingCall
,
并且在 NET5 上包含System.Net.Sockets.SocketError.OperationAborted Программа на вашем хост-компьютере разорвала установленное подключение
如何正确停止从流中读取的过程?
.NET 5 中异常发生变化的事实是正常的。事实是,
HttpClient
在 Framework 4.xWebRequestHandler
和 .NET Core 3 / .NET 5 及更高版本的引擎盖下 -SocketsHttpHandler
从头开始使用更现代的重写 HTTP 引擎。因此,某些地方的例外情况可能会有所不同。只需为新的调试数据重写代码。
当然,你可以用旧的方式
WebRequestHandler
强行推入HttpClient
并获取异常,但我不建议你这样做,因为旧的 HTTP 引擎在效率上比新引擎差得多,而且不支持很多东西现代互联网的条件。