2017-05-30 12 views
0

私が安全にスレッドする方法を把握しようとしていると、パフォーマンスが賢明な問題にConcurrentQueueC#はConcurrentQueue

私の現在のソリューションにTryDequeueを元に戻すにTryDequeueを元に戻すことは次のとおりです。

lock(_queue) { 
    _queue = new ConcurrentQueue<IItem>(_queue.Reverse()); 
    _queue.Enqueue(item); 
    _queue = new ConcurrentQueue<IItem>(_queue.Reverse()); 
} 

しかし、これを行うにはこれが最善の方法であるかどうかは分かりません。なぜなら、手動でロックしているからです。しかし、このプロセス中にキューが別のスレッドで変更されないようにする必要があります。

私はTryPeekをやって、返された項目をチェックし、条件を満たすとTryDequeueを実行し、失敗したらもう一度チェックを行うという理由があります2回目はロールバックをしたい。これは理にかなっていますか?

+2

これはX-Y問題のように聞こえます。すべての可能性が高い、あなたは仕事のために間違ったツールを使用している。 – xxbbcc

+0

@TimSchmelter例のようにオブジェクトを完全に再構築しても? –

+6

実際には、ロックされている参照を置き換えているため、 'lock'は効果がありません。 –

答えて

1

キューからのアクセスをロックする必要がある場合は、ConcurrentQueueの目的は無効になります。普通のQueue<T>の周りに独自のラッパーを書くこともできます。

public class UndoableQueue<T> // I shouldn't be allowed to name anything, ever. 
{ 
    private readonly Queue<T> _queue = new Queue<T>(); 
    private readonly object _lock = new object(); 

    public void Enqueue(T item) 
    { 
     lock (_lock) 
     { 
      _queue.Enqueue(item); 
     } 
    } 

    public bool TryDequeue(Func<T, bool> verify, out T dequeued) 
    { 
     lock (_lock) 
     { 
      if (!_queue.Any()) 
      { 
       dequeued = default(T); 
       return false; 
      } 
      if (verify(_queue.Peek())) 
      { 
       dequeued = _queue.Dequeue(); 
       return true; 
      } 
      dequeued = default(T); 
      return false; 
     } 
    } 
} 

TryDequeueは、アイテムを返すかどうかを決定する関数をとります。 TryDequeueConcurrentQueue)のように動作します。ただし、キューに項目がある場合は値を返します。この項目はtrueを返します。

+0

これはうまくいくかもしれません!どうも –

関連する問題