title: Does Parallel.ForEach Block?
body: <p>Does the .net function <a href="http://msdn.microsoft.com/en-us/library/dd992001.aspx" rel="noreferrer">Parallel.ForEach</a> block the calling thread? My guess as to the behavior is one of these:</p>
  
  <ol>
  <li>Yes, it blocks until the slowest item executing returns.</li>
  <li>No, it doesn't block and returns control immediately. The items to run in parallel are done on background threads.</li>
  </ol>
  
  <p>Or perhaps something else is happening, anyone know for sure?</p>
  
  <p>This question came up when implementing this in a logging class:</p>
  
  <pre><code>public class MultipleLoggingService : LoggingServiceBase
  {
      private readonly List&lt;LoggingServiceBase&gt; loggingServices;
  
      public MultipleLoggingService(List&lt;LoggingServiceBase&gt; loggingServices)
      {
          this.loggingServices = loggingServices;
          LogLevelChanged += OnLogLevelChanged;
      }
  
      private void OnLogLevelChanged(object sender, LogLevelChangedArgs args)
      {
          loggingServices.ForEach(l =&gt; l.LogLevel = LogLevel);
      }
  
      public override LogMessageResponse LogMessage(LogMessageRequest request)
      {
          if (request.LogMessage)
              Parallel.ForEach(loggingServices, l =&gt; l.LogMessage(request));
  
          return new LogMessageResponse{MessageLogged = request.LogMessage};
      }
  }
  </code></pre>
  
  <p>Notice the <code>LogMessage</code> method calls some other logging services. I need that part to return immediately, so it doesn't block the calling thread.</p>
  
  <hr>
  
  <p>Update: Based on comments from others (we have confirmed the behavior is #1). So I have taken advice to use the <a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx" rel="noreferrer">Task</a> library and rewritten the loop like this:</p>
  
  <pre><code>          if (request.LogMessage)
              foreach (var loggingService in loggingServices)
                  Task.Factory.StartNew(() =&gt; loggingService.LogMessage(request));
  </code></pre>