1

プロデューサー/コンシューマーのバインドされたキュー、単一のプロデューサーに対する複数のコンシューマーを実装する必要があります。

アイテムをキューに追加してから最大サイズをチェックするプッシュ機能があります。到達した場合は false を返し、それ以外の場合は true を返します。

次のコードでは、_vector は List<T> であり、onSignal は基本的にアイテムを非同期で消費します。

このコードに問題はありますか?

public bool Push(T message)
{
    bool canEnqueue = true;

    lock (_vector)
    {
        _vector.Add(message);
        if (_vector.Count >= _maxSize)
        {
            canEnqueue = false;
        }
    }

    var onSignal = SignalEvent;
    if (onSignal != null)
    {
        onSignal();
    }

    return canEnqueue;
}
4

2 に答える 2

1

単一プロデューサー、複数コンシューマーと言ったことは知っていますが、とにかく言及する価値があります。キューがほぼ満杯の場合 (25 スロットのうち 24 スロットなど)、Push同時に 2 つのスレッドを実行すると、制限を超えてしまいます。将来のある時点で複数のプロデューサーを持つ可能性さえある場合は、ブロッキング呼び出しを行うことを検討し、アイテムがキューから取り出された後、またはアイテムがキューに入れられた後に通知さPushれる「使用可能」を待機させる必要があります。AutoResetEventまだスロットに空きがあります。

私が見る他の唯一の潜在的な問題はSignalEvent. あなたは私たちにその実装を示していません。として宣言されている場合public event SignalEventDelegate SignalEventは、コンパイラが自動的に . を追加するので問題ありませんSynchronizedAttribute。ただし、/構文でSignalEventバッキング デリゲートを使用する場合は、イベント自体に独自のロックを提供する必要があります。そうしないと、コンシューマーが少し遅れてイベントから切り離され、まだいくつかのシグナルを受信する可能性があります。その後。addremove

編集:実際、それは関係なく可能です。さらに重要なことに、プロパティ スタイルの追加/削除デリゲートを適切なロックなしで使用した場合、デリゲートを実行しようとすると、実際にはデリゲートが無効な状態になる可能性があります。同期されたイベントであっても、コンシューマーは、サブスクライブを解除した後に通知を受け取る (および破棄する) 準備ができている必要があります。

それ以外に問題は見られません - それは何も問題がないという意味ではありませんが、私が気付いていないことを意味します.

于 2010-01-31T02:42:21.047 に答える