Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 流读/写导致死锁?_C#_Concurrency_Stream_Delegates_Deadlock - Fatal编程技术网

C# 流读/写导致死锁?

C# 流读/写导致死锁?,c#,concurrency,stream,delegates,deadlock,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(IAsyncRes

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

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;
    }
}
私有委托流MyDelegate(字符串url);
私有IAsyncResult BeginRequest(异步回调,对象状态)
{
return((MyDelegate)QuerySync).BeginInvoke(url、回调、状态);
}
私有流EndRequest(IAsyncResult结果)
{
返回((MyDelegate)((AsyncResult)结果).AsyncDelegate.EndInvoke(结果);
}
私有流查询同步(字符串url)
{
return(this.client).GetHttpWebResponse(url.GetResponseStream();
}
公共异步任务GetResponseStream(字符串url){
使用(Stream input=await Task.Factory.fromsync(BeginRequest,EndRequest,url,null)。ConfigureAwait(false))
{
var输出=新的MemoryStream();
等待输入。CopyToAsync(输出)。配置等待(false);
输出位置=0;
返回输出;
}
}
而且,由于某些原因,应用程序偶尔会在我的GetResponseStream()方法中停止(不会引发异常,它只是永远挂起)。我环顾四周寻找可能的原因,发现当试图并行读取和写入同一个流时,显然可能会发生死锁。问题是,在这种情况下,我实际上并不是从相同的流中读写(至少我认为是这样)。因为在调用CopyToAsync(显然是在内部执行对该流的读取)之前,我等待最近创建的写入输入流的任务结束,所以只读在写入结束后开始。所以我不明白为什么这会导致死锁,因为我从不同时从同一个流读写


我不知道这是否重要,但作为补充说明,我的QuerySync方法是完全同步的,因为我用于获取响应的客户端当前不支持异步请求。

用于执行这些请求的客户端不是设计为从多个线程并行访问的。您需要创建多个客户机,这样它们就永远不会从单独的线程访问。

同时从多个线程从客户机的响应中获取流显然是个坏主意。它不会期望客户机被设计成让多个线程同时读取其响应流,而这正是您正在做的。如果您希望并行执行多个操作,或者让一个线程读取数据并在将数据放入数据结构后将其暴露给多个线程,请创建多个客户端。@Servy:我试图简化代码,但我想我忽略了一个重要的要求(编辑以澄清这一点)--对GetResponseStream的每次调用都会给出一个传递给客户端的URL,因此每次调用实际上都对应一个不同的响应,因此我无法读取一次数据,然后将其公开。另外,创建多个客户端会破坏应用程序的性能,因为这会增加太多的开销。好吧,选择一个,一个“高性能”的应用程序,因为它不是线程安全的,或者是一个“性能差”的应用程序,它不能工作并且死锁实际工作正常的应用程序。我仍然不清楚死锁的原因。您使用的类不是设计用于多线程中的多线程。当你这样做的时候,任何事情都可能发生,从死锁、异常、错误的结果、世界爆炸等等。