title: DisconnectedContext was detected - Threadpool and Ping
body: <p>I'm attempting to create a multi-threaded application which will allow me to ping thousands of hosts, the results of the ping are written to a richtextbox.</p>
  
  <p>After this application executes, once it's iterated through a thousand or so addresses, I'm presented with the following exception:</p>
  
  <p>DisconnectedContext was detected
  Message: Transition into COM context 0x4410e0 for this RuntimeCallableWrapper failed with the following error: System call failed. (Exception from HRESULT: 0x80010100 (RPC_E_SYS_CALL_FAILED)). This is typically because the COM context 0x4410e0 where this RuntimeCallableWrapper was created has been disconnected or it is busy doing something else. Releasing the interfaces from the current COM context (COM context 0x440f70). This may cause corruption or data loss. To avoid this problem, please ensure that all COM contexts/apartments/threads stay alive and are available for context transition, until the application is completely done with the RuntimeCallableWrappers that represents COM components that live inside them.</p>
  
  <p>I'm not entirely sure what's causing this, I at first figured it was due to my not disposing Ping but I've since addressed that and the problem still persists.</p>
  
  <p>If anyone has any information on this it would be greatly appreciated.</p>
  
  <p>Thank you all.</p>
  
  <pre><code>public static void LogTextEvent(RichTextBox TextEventLog, Color TextColor, string EventText)
      {
          if (TextEventLog.InvokeRequired)
          {
              TextEventLog.BeginInvoke(new Action(delegate { LogTextEvent(TextEventLog, TextColor, EventText); }));
              return;
          }
  
          string nDateTime = DateTime.Now.ToString("hh:mm:ss tt") + " - ";
  
          // color text.
          TextEventLog.SelectionStart = TextEventLog.Text.Length;
          TextEventLog.SelectionColor = TextColor;
  
          // newline if first line, append if else.
          if (TextEventLog.Lines.Length == 0)
          {
              TextEventLog.AppendText(nDateTime + EventText);
              TextEventLog.ScrollToCaret();
              TextEventLog.AppendText(Environment.NewLine);
          }
          else
          {
              TextEventLog.AppendText(nDateTime + EventText + Environment.NewLine);
              TextEventLog.ScrollToCaret();
          }
      }
  
      private void button1_Click(object sender, EventArgs e)
      {
          string[] logFile = File.ReadAllLines("addrs.txt");
          var addresses = new List&lt;string&gt;(logFile);
  
          foreach (string ip in addresses)
          {
              // See http://stackoverflow.com/questions/4744630/unexpected-behaviour-for-threadpool-queueuserworkitem
              // for reason to use another variable in the loop
              string loopIp = ip;
              WaitCallback func = delegate
                  {
                      if (PingIP(loopIp))
                      {
                          LogTextEvent(richTextBox1, Color.Green, "[ " + loopIp.ToUpper() + " ] - Ping Success");
                      }
                      else
                      {
                          LogTextEvent(richTextBox1, Color.Red, "[ " + loopIp.ToUpper() + " ] - Ping FAIL!");
                      }
                  };
  
              ThreadPool.QueueUserWorkItem(func);
          }
      }
  
      public static bool PingIP(string IP)
      {
          bool result = false;
          var ping = new Ping();
          try
          {
              //var ping = new Ping();
              PingReply pingReply = ping.Send(IP);
  
              if (pingReply.Status == IPStatus.Success)
                  result = true;
          }
          catch
          {
              result = false;
          }
          finally
          {
              ping.Dispose();
          }
          return result;
      }
  </code></pre>