流读/写导致死锁?

时间:2015-01-28 16:50:42

标签: c# concurrency stream delegates deadlock

我有以下代码片段,它由多个线程并行执行:

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()方法中停止(没有抛出异常,它只是永久挂起)。我已经四处查找可能的原因,并发现当尝试并行读取和写入同一个Stream时,可能会发生死锁。问题是,在这种情况下,我实际上并没有从相同的流中读取和写入(至少我认为是这样)。因为我等待最近创建的写入输入流的任务在调用CopyToAsync之前结束(显然在内部对此流执行读取),所以只有在写入结束后才开始读取。所以我不明白为什么这会导致死锁,因为我从来没有同时从同一个Stream读取和写入。

我不知道这是否重要,但作为旁注,我的QuerySync方法是完全同步的,因为我用来获取响应的客户端目前不支持异步请求。

1 个答案:

答案 0 :(得分:0)

您用于执行这些请求的客户端并非旨在从多个线程并行访问。您需要创建多个客户端,以便永远不会从不同的线程访问它们。