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 и удвоите число потоков, велика вероятность, что это окажет практически нулевое влияние. С другой стороны, исправление является правильным и простым в обслуживании.

Другие вопросы по тегам