Stream.CopyTo Зависает при использовании с Librsync.PatchStream
Я использую 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);
}
}
1 ответ
В комментариях мы узнали, что это пример "классического тупика ASP.NET".
В идеале вы бы нашли место, где вы используете await
и отсутствуют ConfigureAwait(false)
,
Я не верю, что это ошибка в библиотеке Rsync. призвание Result
задание не запрещено, если обстоятельства требуют его выполнения. Библиотека может предполагать, что это не будет тупик. У него нет возможности проверить, является ли это безопасной операцией, поэтому он должен просто сделать это и полагаться на вызывающих, чтобы обеспечить правильные объекты.
Быстрое решение состоит в том, чтобы обернуть код Rsync в Task.Run(() => ...).Wait();
который эффективно очищает контекст синхронизации на протяжении всего кода. Из-за этого пропавшего ConfigureAwait(false)
не имеет никакого влияния больше.
Это исправление обычно приемлемо. Он снижает производительность, поскольку потребляет еще один поток и требует некоторой синхронизации. Обычно это несущественно. Если вы возьмете случайное приложение ASP.NET и удвоите число потоков, велика вероятность, что это окажет практически нулевое влияние. С другой стороны, исправление является правильным и простым в обслуживании.