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

标签 c# .net stream filestream librsync

我正在使用Librsync在项目中计算文件两个版本之间的差异并将更改应用到旧文件。

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

代码示例 -

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 库中的错误。如果情况需要,则不会禁止对任务调用 Result。库可以假设这不会发生死锁。它无法检查这是否是一个安全操作,因此它必须执行此操作并依赖调用者提供正确的对象。

一个快速修复方法是将 Rsync 代码包装在 Task.Run(() => ...).Wait(); 中,这将有效地清除此代码持续时间内的同步上下文。因此,缺少的 ConfigureAwait(false) 不再有任何影响。

此修复通常是可以接受的。它会产生性能成本,因为它会多消耗一个线程并产生一些同步成本。通常,这是无关紧要的。如果您随机选择一个 ASP.NET 应用程序并将线程数量增加一倍,那么影响几乎为零的可能性很高。从好的方面来说,这个修复显然是正确的并且易于维护。

关于c# - Stream.CopyTo 与 Librsync.PatchStream 一起使用时挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39614115/

相关文章:

c# - Rx 的真实世界示例

c# - .NET Core 2.x 加载引用程序集,代码中没有类型引用

html - Firefox 从缓存流式传输而不是实时流式传输

c++ - 如何使用智能指针进行自动清理?

c# - 如何使用 DateTime.Now.ToString();在 sql 命令中,无需删除斜杠

java - Spring : Download file from REST controller

c# - 在模型中设置 DataType.DateTime 的初始值

c# - 为什么不能在字节变量中存储负值?

c# - 从 wpf 应用程序打开并且 outlook 正在运行时,如何使 outlook 选择名称对话框聚焦

c# - 具有多个 OR 条件的 Linq to Entity Join 表