Stream.CopyTo 与 Librsync.PatchStream 一起使用时挂起
Stream.CopyTo Hangs when used with Librsync.PatchStream
我在一个项目中使用 Librsync 来计算文件的两个版本之间的差异并将更改应用到旧文件。
在我的项目之外,我让它在一个简单的控制台应用程序中工作,该应用程序从 2 个不同的目录读取文件,"Patches" 它们并将其写到一个修补目录中。
代码示例 -
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);
}
}
在评论中我们发现这是 "classic ASP.NET deadlock".
的一个实例
理想情况下,您会找到您正在使用 await
并且缺少 ConfigureAwait(false)
.
的地方
我认为这不是 Rsync 库中的错误。如果情况需要,在任务上调用 Result
并不被禁止。允许库假设这不会死锁。它无法检查这是否是一个安全的操作,所以它必须这样做并依赖调用者提供正确的对象。
一个快速修复方法是将 Rsync 代码包装在 Task.Run(() => ...).Wait();
中,这样可以有效地清除此代码持续时间内的同步上下文。因此,丢失的 ConfigureAwait(false)
不再有影响。
此修复通常是可以接受的。它有性能成本,因为它多消耗一个线程并且有一些同步成本。通常,这是无关紧要的。如果您采用随机 ASP.NET 应用程序并将线程数加倍,则影响几乎为零的可能性很高。从好的方面来看,修复显然是正确的并且易于维护。
我在一个项目中使用 Librsync 来计算文件的两个版本之间的差异并将更改应用到旧文件。
在我的项目之外,我让它在一个简单的控制台应用程序中工作,该应用程序从 2 个不同的目录读取文件,"Patches" 它们并将其写到一个修补目录中。
代码示例 -
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);
}
}
在评论中我们发现这是 "classic ASP.NET deadlock".
的一个实例理想情况下,您会找到您正在使用 await
并且缺少 ConfigureAwait(false)
.
我认为这不是 Rsync 库中的错误。如果情况需要,在任务上调用 Result
并不被禁止。允许库假设这不会死锁。它无法检查这是否是一个安全的操作,所以它必须这样做并依赖调用者提供正确的对象。
一个快速修复方法是将 Rsync 代码包装在 Task.Run(() => ...).Wait();
中,这样可以有效地清除此代码持续时间内的同步上下文。因此,丢失的 ConfigureAwait(false)
不再有影响。
此修复通常是可以接受的。它有性能成本,因为它多消耗一个线程并且有一些同步成本。通常,这是无关紧要的。如果您采用随机 ASP.NET 应用程序并将线程数加倍,则影响几乎为零的可能性很高。从好的方面来看,修复显然是正确的并且易于维护。