Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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# Stream.CopyTo与Librsync.PatchStream一起使用时挂起_C#_.net_Stream_Filestream_Librsync - Fatal编程技术网

C# Stream.CopyTo与Librsync.PatchStream一起使用时挂起

C# Stream.CopyTo与Librsync.PatchStream一起使用时挂起,c#,.net,stream,filestream,librsync,C#,.net,Stream,Filestream,Librsync,我在一个项目中使用它来计算文件的两个版本之间的差异,并将更改应用于旧文件 在我的项目之外,我让它在一个简单的控制台应用程序中工作,该应用程序从两个不同的目录中读取文件,“修补”它们并将其写入一个修补过的目录 代码示例- using (var deltaFile = new FileStream(tmpDeltaFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)) { //myClient is th

我在一个项目中使用它来计算文件的两个版本之间的差异,并将更改应用于旧文件

在我的项目之外,我让它在一个简单的控制台应用程序中工作,该应用程序从两个不同的目录中读取文件,“修补”它们并将其写入一个修补过的目录

代码示例-

using (var deltaFile = new FileStream(tmpDeltaFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
    //myClient is the client of a WCF service I created
    myClient.ComputeDelta(file.Id, signatureStream).CopyTo(deltaFile);

    originalFile.Seek(0, SeekOrigin.Begin);
    deltaFile.Seek(0, SeekOrigin.Begin);
    var patchedStream = Librsync.ApplyDelta(originalFile, deltaFile);

    using (var patchedFileStream = new FileStream(patchedFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
    {
        //Code below just hangs. patchedStream pos = 0 and the length is the same as that of the new file.
        patchedStream.CopyTo(patchedFileStream);
    }
}

在评论中,我们发现这是“经典ASP.NET死锁”的一个实例

理想情况下,您可以找到正在使用
await
且缺少
ConfigureAwait(false)
的位置

我不相信这是Rsync库中的bug。对任务调用
Result
,在环境要求的情况下是不被禁止的。允许库假定这不会死锁。它无法检查这是否是一个安全的操作,因此它必须执行此操作,并依靠调用方提供正确的对象

快速修复方法是将Rsync代码包装到
Task.Run(()=>…).Wait()中
有效清除此代码期间的同步上下文。因此,缺少的
ConfigureAwait(false)
不再有影响


这种修复通常是可以接受的。它有一个性能成本,因为它消耗了一个以上的线程,并有一些同步成本。通常,这是无关紧要的。如果你随机使用一个ASP.NET应用程序,并将线程数增加一倍,那么这几乎没有影响的可能性很高。从正面来看,修复程序显然是正确的,并且易于维护。

暂停调试器并使用外部代码发布手动调用堆栈。挂起-
公共覆盖int-Read(byte[]buffer,int-offset,int-count){return ReadAsync(buffer,offset,count)。Result;}
在PatchedStream.cs中,
.Result
看起来像一个典型的ASP.NET死锁。这是未知代码中的错误。将整个任务包装在
任务中。运行(()=>…).Wait()来测试这个。我按照你的建议做了,文件被成功写入。如果我离开
Task.Run(()=>…).Wait(),这是否可以接受/良好的做法在代码中?