title: Winform: Multiple Threads Updating UI at Same Time
body: <p>I inherited some code that has two non-UI threads that update various WinForm controls.<br>
  The code is using InvokeRequired and Invoke to update the UI; however, I still once in a while get the error: Cross-thread operation not valid: Control 'lvReports' accessed on a thread other than it was created on.</p>
  
  <p>I suspect I am dealing with a race condition and that I need to introduce a lock into the method below, but that said, I can find dozens of examples on how to update UI from a non-UI thread safely but no examples or discussion on how to deal with two threads updating the same controls in a race scenario.</p>
  
  <p>So my question is: how do I rewrite the code below to handle updating the UI properly given a race condition and that I need to update UI from non-UI threads?</p>
  
  <pre><code>// two separate theads call this method in a instance of a WinForm
  private void LoadReports()
  {
    if (this.InvokeRequired)
    {
      this.Invoke(new MethodInvoker(this.LoadReports));
    }
    else
    {
      // some code removed to keep exampe simple...
      SetCtlVisible(lvReports, true);
  
      if (this.InvokeRequired)
      {
        this.Invoke((MethodInvoker)delegate { lvReports.Refresh(); });
      }
      else
      {
         lvReports.Refresh();
      }
    }
  }
  
  delegate void SetVisibleCallback(Control ctl, bool visible);
  private void SetCtlVisible(Control ctl, bool visible)
  {
    if (ctl.InvokeRequired)
    {
      SetVisibleCallback d = new SetVisibleCallback(SetCtlVisible);
      ctl.Invoke(d, new object[] { ctl, visible });
    }
    else
    {
      ctl.Visible = visible;
    }
  }
  </code></pre>
  
  <p>Here are some thoughts:
  Does this.InvokeRequired differ from ctl.InvokeRequired at any time?
  Is the second InvokeRequired test needed given the first?
  Is the implementation of SetCtlVisible needed if I keep the first InvokeRequired?
  Should I delete the first InvokeRequired and keep all the code in the else clause?
  Is lock needed around the else clause?</p>