title: Async Producer/Consumer
body: <p>I have a instance of a class that is accessed from several threads. This class take this calls and add a tuple into a database. I need this to be done in a serial manner, as due to some db constraints, parallel threads could result in an inconsistent database.</p>
  
  <p>As I am new to parallelism and concurrency in C#, I did this:</p>
  
  <pre><code>private BlockingCollection&lt;Task&gt; _tasks = new BlockingCollection&lt;Task&gt;();
  
  public void AddDData(string info)
  {
      Task t = new Task(() =&gt; { InsertDataIntoBase(info); });
      _tasks.Add(t);
  }
  
  private void InsertWorker()
  {
      Task.Factory.StartNew(() =&gt;
      {
          while (!_tasks.IsCompleted)
          {
              Task t;
              if (_tasks.TryTake(out t))
              {
                  t.Start();
                  t.Wait();
              }
          }
      });
  }
  </code></pre>
  
  <p>The <code>AddDData</code> is the one who is called by multiple threads and <code>InsertDataIntoBase</code> is a very simple insert that should take few milliseconds.</p>
  
  <p>The problem is that, for some reason that my lack of knowledge doesn't allow me to figure out, sometimes a task is been called twice! It always goes like this:</p>
  
  <p>T1
  T2
  T3
  T1 &lt;- PK error.
  T4
  ...</p>
  
  <p>Did I understand <code>.Take()</code> completely wrong, am I missing something or my producer/ consumer implementation is really bad?</p>
  
  <p>Best Regards,
  Rafael</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>As suggested, I made a quick sandbox test implementation with this architecture and as I was suspecting, it does not guarantee that a task will not be fired before the previous one finishes.</p>
  
  <p><img src="https://i.stack.imgur.com/Iil9U.png" alt="enter image description here"></p>
  
  <p>So the question remains: how to properly queue tasks and fire them sequentially?</p>
  
  <p><strong>UPDATE 2:</strong></p>
  
  <p>I simplified the code:</p>
  
  <pre><code>private BlockingCollection&lt;Data&gt; _tasks = new BlockingCollection&lt;Data&gt;();
  
  public void AddDData(Data info)
  {
      _tasks.Add(info);
  }
  
  private void InsertWorker()
  {
      Task.Factory.StartNew(() =&gt;
      {
          while (!_tasks.IsCompleted)
          {
              Data info;
              if (_tasks.TryTake(out info))
              {
                  InsertIntoDB(info);
              }
          }
      });
  }
  </code></pre>
  
  <p>Note that I got rid of Tasks as I'm relying on synced InsertIntoDB call (as it is inside a loop), but still no luck... The generation is fine and I'm absolutely sure that only unique instances are going to the queue. But no matter I try, sometimes the same object is used twice.</p>