2

私は を as として使用してBlockingcollectionいますが、ファイル ロックが発生しやすいFIFO queueファイルに対して多くの操作を行っています。キュー内の他のアイテムがたくさんある場合、これは十分な一時停止ですが、空または非常に短い場合は、ファイルがロックされている可能性が高い自体の再発を繰り返してキューを永久にハンマーで打つことを意味します。consumerFIFO queueFIFO queueconsumer

すなわち

consumer busy-> requeue -> consumer busy -> requeue (無制限)

BlockingCollection10 秒未満の新しいコンシューマーを実行しないようにする方法はありますか? つまり、潜在的にキュー内のネット 1 を取得して続行し、createdDateTime が null (最初の試行のデフォルト) である場合、または 10 秒を超える場合にのみ、次の消費者を取得しますか?

4

2 に答える 2

3

それを支援する組み込みのものは何もありません。各作業項目とともに、DateTime最後に試行されたときを保存します (nullこれが最初の試行である可能性があります)。次に、処理関数でTimeSpan.FromSeconds(10) - (DateTime.UtcNow - lastAttemptDateTime)、次の試行を行う前に数秒間待機します。

次回の試行日時が早い順にアイテムを格納する優先キューに切り替えることを検討してください。

于 2015-05-18T12:25:46.310 に答える
2

メイン コレクションと「遅延」コレクションの 2 つのブロッキング コレクションを保持できます。1 つのワーカー スレッドは、遅延したスレッドでのみ機能し、それらをメイン コレクションに読み込みます。拒否されたコレクションの署名は次のようになります。

BlockingCollection<Tuple<DateTime, YourObject>>

今...時間が10秒に固定されている場合、遅延コレクションはほぼDateTimeソートされます(アイテムがほぼ同時に追加された場合、これは真実ではない可能性がありますが、ミリ秒の違いについて話している...問題)

public class MainClass
{
    // The "main" BlockingCollection
    // (the one you are already using)
    BlockingCollection<Work> Works = new BlockingCollection<Work>();

    // The "delayed" BlockingCollection
    BlockingCollection<Tuple<DateTime, Work>> Delayed = new BlockingCollection<Tuple<DateTime, Work>>();

    // This is a single worker that will work on the Delayed collection
    // in a separate thread
    public void DelayedWorker()
    {
        Tuple<DateTime, Work> tuple;

        while (Delayed.TryTake(out tuple, -1))
        {
            var dt = DateTime.Now;

            if (tuple.Item1 > dt)
            {
                Thread.Sleep(tuple.Item1 - dt);
            }

            Works.Add(tuple.Item2);
        }
    }
}
于 2015-05-18T12:58:35.807 に答える