首先,我正在使用Stephen Toub的WithCancellation
扩展来允许我中止ReadStringAsync
方法。 在内部,这使用TaskCompletionSource
和Tasks.WhenAny
。详情请见此处;http://blogs.msdn.com/b/pfxteam/archive/2012/10/05/how-do-i-cancel-non-cancelable-async-operations.aspx
由于 Using
关键字,异常被抛出。 命中End Using
时读取仍在进行,这会释放Response.Content
对象的内部流。 我知道读取仍在后台运行,只要我的代码可以继续而不会卡在长时间读取中,我就不介意。
我不确定在执行此类读取时HttpClient
的超时属性是否适用(请求是用HttpCompletionOption.ResponseHeadersRead
发出的,所以我在读取之前没有内容(。 此外,由于代理错误,我可能遇到代码卡在读取时的问题,因此我需要能够取消它。
我不明白的是;
- 为什么我的 try/catch 块没有捕获异常?
- 如何解决此问题,以便我可以中止读取并忽略异常?
无法删除Using
块,因为所有HttpReponseMessage
对象都包装在Using
中,因此当HttpResponseMessage
被释放时,我遇到了同样的问题。
Public Async Function GetResponseStringAsync(Response As HttpResponseMessage) As Tasks.Task(Of String)
Dim TimeoutToken As New CancellationTokenSource
TimeoutToken.CancelAfter(DefaultTimeout)
Try
Using Response.Content
Try
Return Await Response.Content.ReadAsStringAsync.WithCancellation(TimeoutToken.Token).ConfigureAwait(False)
Catch ex As Exception
End Try
End Using
Catch ex As Exception
End Try
Return Nothing
End Function
这是抛出的InvalidOperationException
的输出。
System.InvalidOperationException: Can not access a closed Stream.
at System.Net.GZipWrapperStream.EndRead(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.EndRead(IAsyncResult asyncResult)
at System.Net.Http.StreamToStreamCopy.BufferReadCallback(IAsyncResult ar)
编辑:72小时后没有评论,赞成或答案。 这个问题有问题吗?
对Response.Content.ReadAsStringAsync
的调用不会阻塞。它立即返回(毕竟它是异步的(,这会从 using 语句的 finally 子句触发对内容的 Dispose 调用,从而关闭基础流并从而导致异常。
尝试读取时,流已关闭。要在读取后处置内容,您可以使用如下延续:
ContinueWith(t => { response.Content.Dispose(); return t.Result; });
希望这有帮助。