Click here to Skip to main content
15,867,832 members
Articles / Desktop Programming / WPF
Article

Extension Methods to Make Thread Safe WPF Programming Easier

Rate me:
Please Sign up or sign in to vote.
3.25/5 (10 votes)
21 Oct 2009CPOL3 min read 37.6K   332   17   9
Provides extension methods for making thread safe UI programming easier

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:

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

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

C#
textBox1.SetTextThreadSafe("Hello World");

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

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

Setting the Text using my extension methods would be:

C#
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:

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

An example Get method:

C#
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)


Written By
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. Pin
E. Scott McFadden15-Dec-10 19:29
professionalE. Scott McFadden15-Dec-10 19:29 
Simon,

The world is filled with people just waiting to tear you down. You article is good and informative. Your pattern is useful at various levels. You improved on Sacha's idea with proper credit and you provided instruction and ideas to others that may not be used to the concept of extensions. I think you did a great job and people like you share ideas for the benefit of all. To some, it may be academic, to others it is a learning experience. Keep publishing even the little things because they add up.

Thanks for sharing and good luck. I hope to see more of your ideas in the future.

Scott
GeneralMy vote of 2 Pin
Yury Goltsman26-Oct-09 23:08
Yury Goltsman26-Oct-09 23:08 
General[My vote of 2] Adding getter/setter properties isn't exactly worth an article Pin
Paul B.26-Oct-09 12:04
Paul B.26-Oct-09 12:04 
JokeRe: [My vote of 2] Adding getter/setter properties isn't exactly worth an article Pin
Simon Knox26-Oct-09 21:51
Simon Knox26-Oct-09 21:51 
GeneralGet/Set typo in article Pin
tpascouche22-Oct-09 4:24
tpascouche22-Oct-09 4:24 
GeneralMy vote of 2 Pin
Wim Reymen21-Oct-09 3:52
Wim Reymen21-Oct-09 3:52 
GeneralRe: My vote of 2 Pin
Simon Knox21-Oct-09 8:15
Simon Knox21-Oct-09 8:15 
GeneralRe: My vote of 2 Pin
BAIJUMAX21-Oct-09 21:54
professionalBAIJUMAX21-Oct-09 21:54 
GeneralRe: My vote of 2 Pin
bciuppa25-Oct-09 10:42
bciuppa25-Oct-09 10:42 

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

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