From BackgroundWorker, to TPL, to Async

I’m back to blogging again.  More on that later…

In any client UI code (WinForms/WPF/Silverilght/WinRT), it’s always a good practice to do as much in the background as possible so you aren’t blocking the UI thread.  “In the old days,” the BackgroundWorker was my best friend when I needed to executed some code in the background.  Along came the Task Parallel Library (TPL), and I moved to using it over Background worker.  Now we have the async enhancements coming soon.  Here’s a comparison of the approaches.

Consider this UI:

   1:  <Window x:Class="WpfApplicationComparingBackground_v_Task.MainWindow"
   2:    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:    Title="MainWindow"
   5:    Height="350"
   6:    Width="525">
   7:    <StackPanel>
   8:      <TextBlock x:Name="Text1" />
   9:      <TextBlock x:Name="Text2" />
  10:      <TextBlock x:Name="Text3" />
  11:    </StackPanel>
  12:  </Window>

And this code behind:

   1:  using System;
   2:  using System.ComponentModel;
   3:  using System.Threading;
   4:  using System.Threading.Tasks;
   5:  using System.Windows;
   6:   
   7:  namespace WpfApplicationComparingBackground_v_Task
   8:  {
   9:      public partial class MainWindow : Window
  10:      {
  11:          public MainWindow()
  12:          {
  13:              InitializeComponent();
  14:   
  15:              Loaded += MainWindow_Loaded;
  16:          }
  17:   
  18:          void MainWindow_Loaded(object sender, RoutedEventArgs e)
  19:          {
  20:              BackgroundWorkerExample();
  21:              TaskContinueWithExample();
  22:              AsyncCtpExample();
  23:          }
  24:   
  25:          private void BackgroundWorkerExample()
  26:          {
  27:              var bWorker = new BackgroundWorker();
  28:   
  29:              bWorker.DoWork += (sender, args) =>
  30:              {
  31:                  // Mimic Some Long Running work
  32:                  Thread.Sleep(TimeSpan.FromSeconds(5));
  33:                  args.Result = "Using BackgroundWorker";
  34:              };
  35:   
  36:              bWorker.RunWorkerCompleted += (sender, args) =>
  37:              {
  38:                  Text1.Text = args.Result.ToString();
  39:              };
  40:   
  41:              bWorker.RunWorkerAsync();
  42:          }
  43:   
  44:          private void TaskContinueWithExample()
  45:          {
  46:              var uiThreadTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
  47:   
  48:              Task<string>.Factory.StartNew(() =>
  49:              {
  50:                  // Mimic Some Long Running work
  51:                  Thread.Sleep(TimeSpan.FromSeconds(5));
  52:   
  53:                  return "Using TPL";
  54:              }).ContinueWith(task =>
  55:              {
  56:                  Text2.Text = task.Result;
  57:              }, uiThreadTaskScheduler);
  58:          }
  59:   
  60:          private async void AsyncCtpExample()
  61:          {
  62:              var response = await Task<string>.Factory.StartNew(() =>
  63:              {
  64:                  // Mimic Some Long Running work
  65:                  Thread.Sleep(TimeSpan.FromSeconds(5));
  66:   
  67:                  return "Using Async CTP";
  68:              });
  69:   
  70:              Text3.Text = response;
  71:          }
  72:      }
  73:  }

Although the TaskContinueWithExample() isn’t much less code than the BackgroundWorkerExample(), it just feels better to me and reads top to bottom which I think is a bit easier to grok.  Of course, the AsyncCtp() example is the least amount of and most readable code.  These three methods accomplish the same goal, but isn’t it nice that the framework / language abstractions have evolved to the simplicity / beauty of AsyncCtpExample()?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s