0

私は通常のリーダー/ライター機能を、キューに入れる 1 つのメイン スレッドとキューから取り出す複数のスレッドを使って書いています。そのため、アイテムの数を整数と比較しているコードの一部がありますConcurrentQueue。これを「maxSize」と呼びましょう。が1.Countを返し、maxSizeが 10 であるにもかかわらず、true を返します。queue.Count >= maxSize

ブレークポイントを使用してデバッグし、デキュー スレッドを 1 つだけ設定して、一時停止しようとしました。これは、メイン スレッドがエンキューされた直後に発生し、数行のコードの後、この比較により 1 >= 10 という結果が返されます。この時点でメイン スレッドがアイテムを 1 つだけ配置すると確信しています。noDequeue()が呼び出されたことは確かです。また、ロックを再確認しようとしましたが、解決しない場合もあります。デバッガーで 1 >= 10 がtrueであることを確認すると、引き裂かれるからです。


int maxSize = 10;
Timer timer;

ctor(int interval)
{
    queue = new ConcurrentQueue<HttpSessionState>();
    timer = new Timer(TimeSpan.FromSeconds(interval).TotalMilliseconds);
    timer.Elapsed += (sender, args) => PulseIfAvailableForProcessing(true);
}

void Process()
{
    queue.Enqueue(obj);
    // interval here is huge, several minutes
    timer.Start();
    PulseIfAvailableForProcessing(false);
}

bool PulseIfAvailableForProcessing(bool isTimeout)
{
    if (isTimeout)
    {
        ...
    }
    else
    {
        // here 1 >= 10 gives true
        if (queue.Count >= maxSize)
        {
            lock (_dataLock)
            {
                // here in debug queue.Count is still 1, however 1 >= 10 returns false
                if (queue.Count >= maxSize)
                {
                    Pulse();
                }
            }
        }
    }
}

絶望してログを追加しましたが、単体テスト中にロックステートメント内でも問題が再現可能であることがわかりました。

4

0 に答える 0