首先,我使用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
的超时属性是否适用(请求是使用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)
的输出。
{{1}}
编辑:72小时后没有评论,赞成或回答。这个问题有问题吗?
答案 0 :(得分:1)
对Response.Content.ReadAsStringAsync
的调用不会阻止。它立即返回(它毕竟是异步),它从using语句的finally子句触发内容上的Dispose调用,关闭底层流,从而导致异常。
在尝试读取时,流已经关闭。要在阅读后处理内容,您可以使用这样的延续:
ContinueWith(t => { response.Content.Dispose(); return t.Result; });
希望这有帮助。