Is BackgroundWorker the only way to keep a WCF/WPF application responsive? Is BackgroundWorker the only way to keep a WCF/WPF application responsive? wpf wpf

Is BackgroundWorker the only way to keep a WCF/WPF application responsive?


No, BackgroundWorker is not the only way, but it's one way. Any other way will allso include some form of asynchronous construct with the need to use Dispatch.BeginInvoke to update the UI. You could for instance use the ThreadPool:

ThreadPool.QueueUserWorkItem(state => {    Dispatcher.BeginInvoke((Action)delegate() { btnRefresh.IsEnabled = false; });    foreach (var user in service.GetAllUsers())        vm.Users.Add(user);    Dispatcher.BeginInvoke((Action)delegate() { btnRefresh.IsEnabled = true; });});

If this is a recurring pattern (a button will trigger some action that should be performed asynchronously, with the button being disabled during the process) you can wrap this into a method:

private void PerformAsync(Action action, Control triggeringControl){    ThreadPool.QueueUserWorkItem(state => {        Dispatcher.BeginInvoke((Action)delegate() { triggeringControl.IsEnabled = false; });        action();        Dispatcher.BeginInvoke((Action)delegate() { triggeringControl.IsEnabled = true; });         });}

...and call it:

PerformAsync(() => {    foreach (var user in service.GetAllUsers())        vm.Users.Add(user);}, btnRefresh);

As an option to using the ThreadPool, you should also perhaps look into the Task Parallel Library.

When doing this you should pay attention to how you handle UI state. For instance of you have more than one control which triggers the same action, make sure that all of them are disabled during the action.

Note: these are just quick ideas. The code has not been tested so it may contain errors. It's more to be regarded as discussion material than finished solutions.


WCF provides the ability to make all service calls asynchronously. When you create the service reference in your project, the add service reference dialog box has an "Advanced..." button. Clicking that you will see the option for "Generate Asynchronous operations". If you click that check-box then every operation will be generated in both a synchronous and asynchronous manner.

For example, if i have an operation "DoSomething()" then after checking this box i will get code generated for calling DoSomething() and DoSomethingAsync().

You will also get a Service.DoSomethingCompleted event that you can use to define a callback handler when the service call returns.

This is the method we used to make service calls without locking the UI.

Here is a rather complicated example provided by Microsoft on how to do this: http://msdn.microsoft.com/en-us/library/ms730059.aspx


It is not the only way. I recommend Task (or one of the higher-level abstractions for Task, such as Parallel or PLINQ).

I have a review of various approaches to asynchronous background operations on my blog.

The current state of things does require some boilerplate code, regardless of which approach you choose. The async CTP shows where things are going - towards a much, much cleaner syntax for asynchronous operations. (Note that - at the time of writing - the async CTP is incompatible with VS SP1).