title: Serializing tasks using a Memory Mapped File
body: <p>I have a bunch of incoming web requests which I need to serialize and process one after each other. I cannot process more than one at a time. My current solution is to run a tool which can be accessed by a Web API using a Memory Mapped File acting as shared memory. I also need a Mutex to allow exclusive access to the shared memory. An event will be used to signal that a task was added.
  So, basically we have there a multiple producers and one consumer. What follows is my first solution. Could someone tell whether or not there are some sort of race conditions or any other problems:</p>
  
  <pre><code>MemoryMappedFile MMF = MemoryMappedFile.CreateNew("Task_Queue", 5000);
  MemoryMappedViewAccessor MMF_Accessor = MMF.CreateViewAccessor();
  
  bool Mutex_Created = false;
  Mutex Mutex = new System.Threading.Mutex(false, "Mutex", out Mutex_Created);
  
  if(Mutex_Created==false)
  {
      // bad error
  
      return;
  }
  
  EventWaitHandle EWH = new EventWaitHandle(false, EventResetMode.ManualReset);
  
  Random Rand = new Random();
  
  
  // Consumer
  // work on the Tasks
  Task.Factory.StartNew(() =&gt;
  {
      while (true)
      {
          // wait until a task has been added
          EWH.WaitOne();
  
          // get exclusive access to read in task
          Mutex.WaitOne();
  
          byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(new string(' ', 5000));
          MMF_Accessor.ReadArray(0, Buffer, 0, Buffer.Length);
  
          int Position = 0;
          foreach (var b in Buffer) { if (b == 0) break; Position++; }
  
          string Message = string.Empty;
  
          for (int i = 0; i &lt; Position; ++i)
          {
              Message += (char)Buffer[i];
          }
  
  
          if(string.IsNullOrEmpty(Message) == false)
          {
              Console.WriteLine(Message);
          }
  
          Mutex.ReleaseMutex();
  
          EWH.Reset();
      }
  });
  
  
  
  // Producer
  // via a web request
  Task.Factory.StartNew(() =&gt;
  {
      while (true)
      {
          if(EWH.WaitOne(0))
          {
              // consumer must take in the task first
  
              // wait a bit and then try again
              Thread.Sleep(100);
  
              break;
          }
  
          // wait until we access Shared Memory and claim it when we can
          Mutex.WaitOne();
  
          string Request = "Task 1 ";
  
          byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(Request);
          Buffer[Buffer.Length - 1] = 0;
  
          MMF_Accessor.WriteArray(0, Buffer, 0, Buffer.Length);
  
          // Signal that a tasks has been added to shared memory
          EWH.Set();
  
          // release the mutex so that others can use the shared memory
          Mutex.ReleaseMutex();
  
          Thread.Sleep(Rand.Next(10, 1000));
      }
  });
  
  // Producer
  // via a web request
  Task.Factory.StartNew(() =&gt;
  {
      while (true)
      {
          // wait until we access Shared Memory and claim it when we can
          Mutex.WaitOne();
  
          string Request = "Task 2 ";
  
          byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(Request);
          Buffer[Buffer.Length - 1] = 0;
  
          MMF_Accessor.WriteArray(0, Buffer, 0, Buffer.Length);
  
          // Signal that a tasks has been added to shared memory
          EWH.Set();
  
          // release the mutex so that others can use the shared memory
          Mutex.ReleaseMutex();
  
          Random r = new Random();
          Thread.Sleep(Rand.Next(10, 1000));
      }
  });
  
  while (Console.Read() != 'q') ;
  </code></pre>
  
  <p>Please note the posted code is just for demonstration purposes.</p>