Welcome to weblogs.com.pk Sign in | Join | Help

BackgroundWorker and delegates

If you are developing some Windows Forms application, and doing some synchronous backend calls which is freezing your UI...Bring asynchronization with few lines of code using BackgroundWorker and delegates..

Consider this original code

   1:  if (null != this.smsGateway) 
   2:  { 
   3:      this.textBoxDetails.Text = string.Format("Wait downloading info for user [{0}]", subscriberName);
   4:      BigCatsDataSet ds = this.smsGateway.GetBillingInfo(subscriberName); 
   5:      if (null!=ds) 
   6:      { 
   7:          foreach (BigCatsDataSet.DataTableBillingProfilesRow user in ds.DataTableBillingProfiles) 
   8:          { 
   9:              if (user.SubscriberUserName.Equals(subscriberName)) 
  10:              { 
  11:                  if (!user.IsUplinkInKbpsNull() && !user.IsDownlinkInKbpsNull()) 
  12:                  { 
  13:                      this.comboBoxUplink.Text = user.UplinkInKbps.ToString(); 
  14:                      this.comboBoxDownlink.Text = user.DownlinkInKbps.ToString(); 
  15:                      this.textBoxDetails.Text = user.Description; 
  16:                      this.checkBoxIsCir.Checked = user.IsIsCirNull() ? false : user.IsCir;
  17:                  } 
  18:              } 
  19:          } 
  20:      } 
  21:  } 
  22:  else 
  23:      this.ErrorOccurred(this, new MvpViewArgs("this.smsGateway is not yet initialized!"));

Using Insert Code for Windows Live Writer Addin above!

this.smsGateway.GetBillingInfo() method is the one that might be freezing your UI. To make this code asynchronous, we will simply wrap this call in the BackgroundWorker's DoWork event and move the rest into its RunWorkerCompleted event. And this can be easily done using delegates...i-e no need of separate methods for these two events implementation! The issue we will hit is that as the call will happen in separate thread from where we cannt access the controls (the couple of controls being set by the returned values). This can be resolved using control' BeginInvoke method and again with delegates, its quite straightforward...

   1:  if (null != this.smsGateway)
   2:  {
   3:      string details = string.Format("Wait downloading info for user [{0}]", subscriberName);
   4:      this.textBoxDetails.Text = details;
   5:      BigCatsDataSet ds = null;
   6:   
   7:      BackgroundWorker worker = new BackgroundWorker();
   8:      worker.DoWork += delegate(object sender, DoWorkEventArgs e)
   9:      {
  10:          ds = this.smsGateway.GetBillingInfo(subscriberName);
  11:      };
  12:      worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e)
  13:      {
  14:          if (null != ds)
  15:          {
  16:              foreach (BigCatsDataSet.DataTableBillingProfilesRow user in ds.DataTableBillingProfiles)
  17:              {
  18:                  if (user.SubscriberUserName.Equals(subscriberName))
  19:                  {
  20:                      if (!user.IsUplinkInKbpsNull() && !user.IsDownlinkInKbpsNull())
  21:                      {
  22:                          this.BeginInvoke(new MethodInvoker(delegate()
  23:                          {
  24:                              this.comboBoxUplink.Text = user.UplinkInKbps.ToString();
  25:                              this.comboBoxDownlink.Text = user.DownlinkInKbps.ToString();
  26:                              this.textBoxDetails.Text = user.Description;
  27:                              this.checkBoxIsCir.Checked = user.IsIsCirNull() ? false : user.IsCir;
  28:                          }));
  29:                      }
  30:                  }
  31:              }
  32:          }
  33:      };
  34:      worker.RunWorkerAsync();
  35:  }
  36:  else
  37:      this.ErrorOccurred(this, new MvpViewArgs("this.smsGateway is not yet initialized!"));
Published Thursday, October 09, 2008 3:22 PM by khurram
Filed under:

Comments

# re: BackgroundWorker and delegates

Saturday, October 11, 2008 12:01 PM by Khurram

I beleive, we dont need BeginInvoke in RunWorkerCompleted event...

While refactoring the above code, I didnt wanted to take any risk and didnt had much time to test...thats why I choosed the safe option before checking in...

If someone can confirm this, would be great...

# re: BackgroundWorker and delegates

Sunday, October 12, 2008 4:18 PM by nasir
New Comments to this post are disabled