title: Unexpected data loss during static Queue.Enqueue in multithread process
body: <pre class="lang-cs prettyprint-override"><code>private Queue&lt;FrameObjectElement&gt; _queueObject = new
  Queue&lt;FrameObjectElement&gt;();
  
  private static Queue&lt;FrameObjectElement&gt; _queueItem = new
  Queue&lt;FrameObjectElement&gt;();
  
  private static int permitEntryCount = 0;
  
  private int allowThreadEntry = 0;
  </code></pre>
  <p>I have 2 queue variables as shown above.</p>
  <pre class="lang-cs prettyprint-override"><code>public Camera(IVideoSource source, MotionDetector detector)
  {
      VideoSource = source; 
      _motionDetector = detector;
      VideoSource.NewFrame += VideoNewFrame; 
      MainForm.OnRegisterClickedEvent += new MainForm.RegisterClickedEventHandler(MainForm_OnRegisterClickedEvent);
      MainForm.OnReceiveMultipleFrameEvent += new MainForm.ReceiveMultipleFrameEventHandler(MainForm_OnReceiveMultipleFrameEvent);
  }
  </code></pre>
  <p>I have a Camera class, and shown above is part of the constructor implementation. The video source always listening to event <code>VideoNewFrame;</code> The code I show below is one segment of the code in <code>VideoNewFrame</code>.</p>
  <pre class="lang-cs prettyprint-override"><code>FrameObjectElement frameObj = new FrameObjectElement();
  frameObj.cameraID = CW.Camobject.id;
  frameObj.cameraTag = _FPGAFrameCount / 2;
  frameObj.FirstFrameBuffer = BitmapToRgbValues(twoframe_arg.GetFirstBitmap(352, 288));
  frameObj.SecondFrameBuffer = BitmapToRgbValues(twoframe_arg.GetSecondBitmap(352, 288));
  
  if (_queueObject.Count &gt; 5)
      _queueObject.Clear();
  
  _queueObject.Enqueue(frameObj);
  
  if (allowThreadEntry == permitEntryCount &amp;&amp; isClear) 
  {
      if (_queueObject.Count !=  0)
      {
          lock (this)
          {
              _queueItem.Enqueue(_queueObject.Peek());
          }
          Debug.WriteLine(&quot;Thread ID: &quot; + Thread.CurrentThread.ManagedThreadId.ToString() +
          &quot; - &quot; + _queueObject.Count.ToString() +
          &quot; queue in QueueObject : Camera ID : &quot; + _queueObject.Peek().cameraID.ToString() +
          &quot; : Camera Tag : &quot; + _queueObject.Peek().cameraTag.ToString() + 
          &quot; : Queue item count : &quot; + _queueItem.Count.ToString());
  
          _queueObject.Dequeue();
  
          if (_queueItem.Count == numberOfCamera &amp;&amp; isAllow)
          {
              CurrentID = CW.Camobject.id;
              isAllow = false;
          }
  
          allowThreadEntry++;
          if (_queueItem.Count == numberOfCamera)
          {
              if (CurrentID == CW.Camobject.id)
              {
                  isClear = false;
                  //allowEntry = false;
  
                  //Debug.WriteLine(&quot;-- Count: &quot; + allowThreadEntry.ToString() + &quot; --&quot;);
  
                  foreach (FrameObjectElement foE in _queueItem)
                  {
                      Debug.WriteLine(&quot;Current Camera ID: &quot; + CW.Camobject.id +
                          &quot; : Camera ID : &quot; + foE.cameraID.ToString() +
                          &quot; : Camera Tag : &quot; + foE.cameraTag.ToString() + &quot; :&quot;);
                  }
  
                  MultipleFrameEventArgs newMul = new MultipleFrameEventArgs();
                  newMul.itemObj = _queueItem;
  
                  if (OnMultupleFrameEvent != null)
                      OnMultupleFrameEvent(newMul);
  
                  _queueItem.Clear();
                  isAllow = true;
                  isClear = true;
                  Debug.WriteLine(&quot;Queue item count: &quot; + _queueItem.Count.ToString() +
                      &quot; : isClear : &quot; + isClear.ToString());
              }
          }   
      }
  }
  </code></pre>
  <p>Basically what am I trying to achieve here is to collect the frame id, tag, its first and second frame and then store in an object(<code>struct FrameObjectElement</code>). Every collection of 2 frames will represent 1 camera tag, thus the meaning of its role here. Then the frameobject is enqueued in <code>_queueObject</code>. Next I would have a condition <code>if(allowThreadEntry == permitEntryCount)</code>. So what is being done here is every time this function is accessed, <code>allowThreadEntry</code> will increment while <code>permitCountEntry</code> remains the same. Then this function will go on and enqueue the first element in <code>_queueObject</code> to <code>_queueItem</code> and once a desired count of <code>_queueItem</code> is satisfied, it would raise a signal to another Class. This class will respond back by raising a signal which Camera class has earlier subscribed as shown <code> MainForm.OnReceiveMultipleFrameEvent += new MainForm.ReceiveMultipleFrameEvent(MainForm_OnReceiveMultipleFrameEvent)</code>.</p>
  <pre class="lang-cs prettyprint-override"><code>void
  MainForm_OnReceiveMultipleFrameEvent(MainForm.ReceiveMultpleFrameEventArgs
  e)  {       permitEntryCount++;     }
  </code></pre>
  <p>Upon receiving the signal, <code>permitEntryCount</code> will be incremented thus allowing the function to be accessed again. Why I do this is because this class is created depends on how many object camera I have. If I have 11 cameras, I would have 11 <code>workerThread</code> running processing this class. I queue up their frames in a non static queue and gather their first element into a static queue which is to be passed for my other process. The problem I am facing here is as below:</p>
  <pre class="lang-none prettyprint-override"><code>=============================  Count : 1760 ===============================
  Queue item count: 0 : isClear : True
  Thread ID: 17 - 3 queue in QueueObject : Camera ID : 3 : Camera Tag :
  3372 : Queue item count : 1
  Thread ID: 24 - 6 queue in QueueObject : Camera ID :10 : Camera Tag :
  4367 : Queue item count : 2
  Thread ID: 23 - 5 queue in QueueObject : Camera ID : 9 : Camera Tag :
  4415 : Queue item count : 3
  Thread ID: 19 - 1 queue in QueueObject : Camera ID : 5 : Camera Tag :
  4108 : Queue item count : 4
  Thread ID: 20 - 5 queue in QueueObject : Camera ID : 6 : Camera Tag :
  3768 : Queue item count : 5
  Thread ID: 14 - 1 queue in QueueObject : Camera ID : 0 : Camera Tag :
  2837 : Queue item count : 6
  Thread ID: 21 - 1 queue in QueueObject : Camera ID : 7 : Camera Tag :
  3246 : Queue item count : 7
  Thread ID: 16 - 1 queue in QueueObject : Camera ID : 2 : Camera Tag :
  3552 : Queue item count : 8
  Thread ID: 18 - 6 queue in QueueObject : Camera ID : 4 : Camera Tag :
  3117 : Queue item count : 9
  Thread ID: 15 - 3 queue in QueueObject : Camera ID :1 : Camera Tag :
  2315 : Queue item count : 10
  Thread ID: 22 - 4 queue in QueueObject : Camera ID :8 : Camera Tag :
  4853 : Queue item count : 11
  Current Camera ID: 8 : Camera ID : 3 : Camera Tag : 3372 :
  Current Camera ID: 8 : Camera ID :10 : Camera Tag : 4367 :
  Current Camera ID: 8 : Camera ID : 9 : Camera Tag : 4415 :
  Current Camera ID: 8 : Camera ID : 5 : Camera Tag : 4108 :
  Current Camera ID: 8 : Camera ID : 6 : Camera Tag : 3768 :
  Current Camera ID: 8 : Camera ID : 0 : Camera Tag : 2837 :
  Current Camera ID: 8 : Camera ID : 7 : Camera Tag : 3246 :
  Current Camera ID: 8 : Camera ID : 2 : Camera Tag : 3552 :
  Current Camera ID: 8 : Camera ID : 4 : Camera Tag : 3117 :
  Current Camera ID: 8 : Camera ID : 1 : Camera Tag : 2315 :
  Current Camera ID: 8 : Camera ID : 8 : Camera Tag : 4853 :
  =============================  Count : 1761 ===============================
  Queue item count: 0 : isClear : True
  Thread ID: 14 - 1 queue in QueueObject : Camera ID : 0 : Camera Tag :
  2838 : Queue item count : 1
  Thread ID: 16 - 1 queue in QueueObject : Camera ID : 2 : Camera Tag :
  3553 : Queue item count : 2
  Thread ID: 21 - 1 queue in QueueObject : Camera ID : 7 : Camera Tag :
  3247 : Queue item count : 3
  Thread ID: 24 - 1 queue in QueueObject : Camera ID :10 : Camera Tag :
  4374 : Queue item count : 4
  Thread ID: 23 - 6 queue in QueueObject : Camera ID : 9 : Camera Tag :
  4416 : Queue item count : 5
  Thread ID: 17 - 4 queue in QueueObject : Camera ID : 3 : Camera Tag :
  3373 : Queue item count : 7
  Thread ID: 15 - 3 queue in QueueObject : Camera ID : 1 : Camera Tag :
  2316 : Queue item count : 7
  Thread ID: 18 - 6 queue in QueueObject : Camera ID : 4 : Camera Tag :
  3118 : Queue item count : 8
  Thread ID: 20 - 6 queue in QueueObject : Camera ID : 6 : Camera Tag :
  3769 : Queue item count : 9
  Thread ID: 22 - 4 queue in QueueObject : Camera ID :8 : Camera Tag :
  4854 : Queue item count : 10
  </code></pre>
  <p>I should have different count number in <code>_queueItem</code> since every object created can access only one time in this segment thus letting me know that their element will be enqueued into <code>_queueItem</code>. But unfortunately, somehow after the program runs a while, there will be an occurrence as shown above. Either I apply lock or not on this part <code>_queueItem.Enqueue(_queueObject.Peek());</code> I will still have the problem. May I know where I did wrong?</p>