title: Can this cause deadlock? BeginInvoke() & thread.Join()
body: <p>I have this code that many threads can call to update the GUI:</p>
  
  <pre><code>MethodInvoker del = () =&gt; { lblInfo.Text = tmp; };
  lblInfo.BeginInvoke(del);
  </code></pre>
  
  <p>(lblInfo is created by the GUI thread)</p>
  
  <p>I also have this method called at button click executed by the GUI thread:</p>
  
  <pre><code>public void Stop()
  {
      isStopping = true;
      crawler.Join();
      foreach (Thread t in txtWorkers)
      {
          t.Join();
      }
      indexer.Join();     
      lblStatus.Text = "Stopped";
      lblInfo.Text = "";
  }
  </code></pre>
  
  <p>1 time over 100 run the program deadlock at Stop button click. I was not debugging when i saw the deadlock so i can't be sure about the state of the various threads but i'm almost sure that all the threads i'm joining will eventually reach the point where they check for 
  <code>isStopping</code> value and terminate. This leads me to think that there may be a problem with the <code>BeginInvoke</code> but can't really find it. It should be async so threads calling it (crawler &amp; indexer) should not block. What happens if the GUI thread is executing <code>Stop()</code> and also must execute a call from <code>BeginInvoke</code>? Could this be the problem? Is there something i can't see about the thread i'm joining?</p>
  
  <p><strong>EDIT:</strong>
  What the code looks like after the suggested changes:</p>
  
  <pre><code>public void Stop()
  {
      /*
       ...disable GUI
       */
  
      isStopping = true; // Declared as volatile
      lblStatus.Text = "Stopping...";
  
      // Creating a thread that will wait for other threads to terminate
      Task.Factory.StartNew(() =&gt;
      {    
          crawler.Join();
          foreach (Thread t in txtWorkers)
          {
              t.Join();
          }
          indexer.Join();
  
          // Adjust UI now that all threads are terminated
          MethodInvoker del = () =&gt;
          {
              /*
              ...enable GUI
              */
              lblStatus.Text = "Not Running";
              isStopping = false;
          };
          lblStatus.BeginInvoke(del);
      });
  }
  </code></pre>
  
  <p>It seems to be working, i hope that deadlock is gone... </p>