2

プロジェクトでLibrsyncを使用して、ファイルの2つのバージョン間の違いを計算し、変更を古いファイルに適用しています。

私のプロジェクトの外では、2つの異なるディレクトリからファイルを読み取り、それらを「パッチ」して、パッチが適用されたディレクトリに書き込む単純なコンソールアプリで動作させました。

コードサンプル -

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);
    }
}
4

1 に答える 1

2

コメントで、これが「従来の ASP.NET デッドロック」のインスタンスであることがわかりました。

await理想的には、使用していて不足している場所を見つけることができますConfigureAwait(false)

これは Rsync ライブラリのバグではないと思います。Result状況に応じて、タスクを呼び出すことは禁止されていません。ライブラリは、これがデッドロックしないと想定できます。これが安全な操作であるかどうかを確認する方法がないため、それを行い、正しいオブジェクトを提供するために呼び出し元に依存する必要があります。

Task.Run(() => ...).Wait();簡単な修正は、このコードの実行中に同期コンテキストを効果的にクリアするRsync コードをラップすることです。そのため、欠落ConfigureAwait(false)はもはや影響を与えません。

通常、この修正は受け入れられます。スレッドをもう 1 つ消費し、同期コストがいくらかかかるため、パフォーマンス コストがかかります。通常、これは重要ではありません。ランダムな ASP.NET アプリを使用してスレッド数を 2 倍にすると、影響がほぼゼロになる可能性が高くなります。利点として、修正は明らかに正しく、保守も容易です。

于 2016-09-27T09:06:03.673 に答える