Saturday 14 June 2008

InvokeRequired

One thing that initially confused me when beginning to learn C# with Visual C# 2008 Express, was the complaints made by the debugger when a cross-thread operation was carried out while trying to modify a GUI Control object.

Doing this is a big no-no as it screws up the message pump operation used by Windows to service all GUI objects running on the user interface thread.

The solution to this is to use the .InvokeRequired property of the Control you are trying to access, as in the following code snippet:

   1:  private void SetText(String txt)
   2:  {
   3:      if (this.InvokeRequired)
   4:      {
   5:          BeginInvoke(new MethodInvoker(delegate() { this.SetText(txt); }));
   6:      }
   7:      else
   8:      {
   9:          // Update the text
  10:          this.Text = txt;
  11:      }
  12:  }


In this example, I want to change the title text of the form. To do this, the method SetText is called, and the InvokeRequired property is checked. If the calling thread is the same as the UI thread, InvokeRequired will be false, and the text can be modified with no problem.

However, if the calling thread is NOT the same as the UI, then InvokeRequired will be true, and as such the method is called again via the delegate call. This will ensure the SetText method is called from the UI thread and the text can be adjusted without any complaints form the debugger.

0 comments: