title: Conditionally handle and remove messages by multiple consumers from a MSMQ queue
body: <p>I found this <a href="https://stackoverflow.com/q/5115832/498298">related question</a> but my situation is a little bit different.</p>
  
  <p>I have a ASP.NET application that produces long running tasks that should be processed by a number of background processes (Windows Services). Most of the tasks are similar and can be handled by most task runners. Due to different versions of the client application (where the tasks are generated by users) some tasks can only be processed by task runners of specific version. The web server has no knowledge about the kind of task. It just sends all the tasks to the same queue using MSMQ.</p>
  
  <p>If a task enters the queue, the next free task runner should receive the task, decide if he can handle this kind of task, remove the task from the queue and run the task.</p>
  
  <p>If the runner that received the message is not able to process this kind of task, it should put back the message to the queue, so that another runner can have a look on the message.</p>
  
  <p>I tried to implement a conditional receive using a transaction, that I can abort if the task has the wrong format:</p>
  
  <pre><code>transaction.Begin();
  var msg = queue.Receive(TimeSpan.FromSeconds(1000), transaction);
  if (CanHandle(msg))
  {
      transaction.Commit();
      // handle
  }
  else
  {
      transaction.Abort();
  }
  </code></pre>
  
  <p>It seems to work, but I don't know if this is the preferable way do go.</p>
  
  <p>Another problem with this solution is, if there is no other free runner that can handle this message I will receive it again and again.</p>
  
  <p>Is there a way I can solve this problem only using MSMQ? The whole task data is already stored in a SQL database. The task runner accesses the task data over a HTTP API (Thats why I rule out solution like SQLServer Service Broker). The data sent to the message queue is only meta data used to identify the job.</p>
  
  <p>If plain MSMQ is not the right tool, can I solve the problem using MassTransit (I didn't like the fact that I have to install and run the additional MassTransit RuntimeServices + SQL db for it) for example? Other suggestions?</p>