This is a mirror of official site: http://jasper-net.blogspot.com/

Ways to work on the main thread (2)

| Wednesday, May 12, 2010
As I promised, this post follows the previous one and suggests another solution for the invocation to the main thread.


A reminder:

We want to perform an operation in a background thread but when our Work is done update something on the main thread.
Here the BackgroundWorker class comes.

- Handles the try/catch within the 'Do_Work' function
- Invocation to main thread is automatic inside the 'work_Completed' delegate function.

The simplest way is:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace BackgroundWorkerPost
{
   public partial class Form1 : Form
   {
          private BackgroundWorker Worker;
          public Form1(){InitializeComponent();
          this.button1.Click += new EventHandler(button1_Click);
         
          //Setting main thread name for better logging
          Thread.CurrentThread.Name = "Main_Tread";
   }
 
    /// <summary>
    /// Start button event click handler
    /// </summary>
    private void button1_Click(object sender, EventArgs e)
    {
          Worker = new BackgroundWorker();
          Worker.DoWork += new DoWorkEventHandler(Worker_DoWork);
          Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
          Worker.RunWorkerAsync();
    }

    /// <summary>
    /// The actual job to do
    /// </summary>
    private void Worker_DoWork(object sender, DoWorkEventArgs e)
    {
         //no need try/catch
         Thread.CurrentThread.Name = "Job_Thread";
         Console.WriteLine("Worker Do_Work, In thread: " + Thread.CurrentThread.Name);

         //do some work
         for (int i = 0; i < 100; i++)
         {
               Thread.Sleep(i);
               Console.WriteLine("Sleep:" + i);
         }
 
         //Set the result to pass Job completed function
         e.Result = "Done";
     }

    /// <summary>
    /// Event handler of work completion
    /// </summary>
    private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {

         //here we return to main thread automatically - no need to Control.Invoke/ Dispatcher.Invoke
         Console.WriteLine("Worker Run_Completed, in thread: " + Thread.CurrentThread.Name);

         if (e.Error != null) //in case of exception thrown from the Do_Work function
         {
               //update some ui control from here
               this.label1.Text = e.Error.Message;
         }
         else
         {
               //update some ui control from here
               this.label1.Text = (string)e.Result;
         }
    }
  }
}

This class is very useful and has a lot more to offer.
You can use it's ProgressUpdate delegate: process an object to it or/and set data to the returned value.

Read more: GalinaK

Posted via email from jasper22's posterous

0 comments: