我有以下代码片段,由多个线程并行执行:
private delegate Stream MyDelegate(string url);
private IAsyncResult BeginRequest(AsyncCallback callback, object state)
{
return ((MyDelegate)QuerySync).BeginInvoke(url, callback, state);
}
private Stream EndRequest(IAsyncResult result)
{
return ((MyDelegate)((AsyncResult)result).AsyncDelegate).EndInvoke(result);
}
private Stream QuerySync(string url)
{
return (this.client).GetHttpWebResponse(url).GetResponseStream();
}
public async Task<Stream> GetResponseStream(string url){
using (Stream input = await Task<Stream>.Factory.FromAsync(BeginRequest, EndRequest, url, null).ConfigureAwait(false))
{
var output = new MemoryStream();
await input.CopyToAsync(output).ConfigureAwait(false);
output.Position = 0;
return output;
}
}
而且,由于某种原因,应用程序偶尔在我的 GetResponseStream() 方法中停止(没有抛出异常,它只是永远挂起)。我四处寻找可能的原因,发现在尝试并行读取和写入同一流时可能会发生死锁。问题是,在这种情况下,我实际上并没有从同一个流中读取和写入(至少我认为是这样)。因为由于我在调用 CopyToAsync 之前等待最近创建的写入输入流的任务结束(显然在内部执行对此流的读取),因此读取仅在写入结束后开始。所以我不明白为什么这会导致死锁,因为我从未同时从同一个流中读取和写入。
我不知道这是否重要,但作为旁注,我的 QuerySync 方法是完全同步的,因为我用于获取响应的客户端当前不支持异步请求。
用于执行这些请求的客户端不是为从多个线程并行访问而设计的。 您需要创建多个客户端,以便永远不会从单独的线程访问它们。