Click here to Skip to main content
Click here to Skip to main content

Extension Methods to Make Thread Safe WPF Programming Easier

By , 21 Oct 2009
Rate this:
Please Sign up or sign in to vote.

Introduction

When writing multi-threaded WPF applications, you must ensure that you don't attempt to access any UI elements from any thread other than the main thread. This can lead to repetitive and untidy looking code. Using extension methods, we will look at a simplified method of providing thread safe UI updating.

Background

Sacha Barber presented a method for thread safe UI updating in his article, Useful WPF Threading Extension Method. This article extends his idea and provides a simpler coding construct.

The Example Application

When you run the example application, you can click on the Start button. This will start a timer that will fire every second. Click Stop to stop the timer. When the Thread Safe Mode CheckBox is checked, the UI Elements in the blue box will update every second. If the Thread Safe Mode checkbox is not checked, an exception will occur. When the timer is not running, you can also click on the Update from UI button. This will update the controls in the blue box regardless of Thread Safe Mode being checked or not because it calls UpdateControls from the UI thread.

Using the Code

Using Sacha's original Extension method, the text for textBox1 would be set like this:

this.InvokeIfRequired(() =>
{
	textBox1.Text = "Hello World";
},
DispatcherPriority.Background);

Using my extension methods, the text for textBox1 would be set like this:

textBox1.SetTextThreadSafe("Hello World");

To get the Text of textBox1 using Sacha's extension method would be:

string s = "";
this.InvokeIfRequired(() =>
{
	s = textBox1.Text = "Hello World";
},
DispatcherPriority.Background);

Setting the Text using my extension methods would be:

string s = textBox1.GetTextThreadSafe();

How Does it Work?

We simply define a Get and Set method for the value we want to get or set. For convenience, I have put these methods in the same static class as the InvokeIfRequired method.

An example Set method:

 public static string SetTextThreadSafe(this TextBox tb)
{
	string s = "";
	InvokeIfRequired(tb, () => { s = tb.Text; }, DispatcherPriority.Background);
	return s;
}

An example Get method:

public static void SetTextThreadSafe(this TextBox tb, string s)
{
	InvokeIfRequired(tb, () => { tb.Text = s; }, DispatcherPriority.Background);
}

An extension method must be contained in a static class. Extension methods must also be declared as static methods. The definition of extension methods looks slightly strange because the first parameter is defined with the keyword this followed by the type that the method extends and then the name to use in the method for the instance. Only the first parameter is defined this way. The rest of them are defined normally.

It is best to try and create these methods for the most general class that has the property you want to use. This will prevent you from having to create similar methods for each control type. An example would be the Visibility property. This is a property of UIElement so it would make sense to create a Set and Get method for UIElement rather than one for RadioButton and another for Label, etc.

Once an extension method is defined, it can be used by any instance of the type defined in the declaration or any type that derives from that type. It can also be called statically.

Questions and Answers

Wouldn't It Be Easier to Just Use the InvokeIfRequired Method?

If you only had to use it once or twice, this may be the case. If you are going to access multiple UI elements multiple times, I think my extension methods are easier.

Do I Have to Write an Extension Method for Every UI Element Property?

Otherwise you will need to use the InvokeIfRequired method each time you access a property of a UI element, so why not wrap it inside an extension method and then you only have to do it once? You can then use your WPFThreadingExtensions class in any applications that need it.

I Don't See a Set or Get Extension Method for the Property I Require?

I have provided a few examples of Get and Set extension methods in the test application so you can use these to help you see how to write your own extension methods.

What Do I Do if I Want to Use a Different DispatcherPriority?

I have used DispatcherPriority.Background in my extensions methods. You could change this, create an extension method that takes the DisplatcherPriority you require as a parameter or use the InvokeIfRequired extension method.

History

  • 20th October, 2009: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Simon Knox
Software Developer (Senior)
United Kingdom United Kingdom
Wrote my first program back in 1981 in BASIC on my ZX81. I have done all the usual languages that you end up learning at university, Pascal, C, C++, Haskell, Prolog. Commercially I have developed in C++ and for the past 8 years C#. I am now living and working in London creating applications in the areas of Banking and Finance in C#.

Comments and Discussions

 
GeneralNice Idea. PinmemberE. Scott McFadden15-Dec-10 19:29 
GeneralMy vote of 2 PinmemberYury Goltsman26-Oct-09 23:08 
General[My vote of 2] Adding getter/setter properties isn't exactly worth an article PinmemberPaul B.26-Oct-09 12:04 
JokeRe: [My vote of 2] Adding getter/setter properties isn't exactly worth an article PinmemberSimon Knox26-Oct-09 21:51 
GeneralGet/Set typo in article PinmemberThomas Pascouche22-Oct-09 4:24 
GeneralMy vote of 2 PinmemberMember 269784121-Oct-09 3:52 
GeneralRe: My vote of 2 PinmemberSimon Knox21-Oct-09 8:15 
GeneralRe: My vote of 2 PinmemberBAIJUMAX21-Oct-09 21:54 
GeneralRe: My vote of 2 Pinmemberbciuppa25-Oct-09 10:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140415.2 | Last Updated 21 Oct 2009
Article Copyright 2009 by Simon Knox
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid