Using Background Worker in C#

27. November 2009 15:42

.NET Framework C# 

Performance of an application matters a lot for a developer. None of the developer wants his application freezes or crashes. But what are measures a developer should takes to keep it all good going. When I used to develop application I saw whenever I try to perform some heavy or bulky task like uploading files, copying files from place to other and other DB related but heavy task which includes CPU as well as hard drive.

Most of our application that we develop today require simultaneous functions to perform but with performance. We guarantee our client…yes the application can handle all the functions but on the stake of performance. The major fallback of any application is limiting a user to perform one task at a time. So how do we deal with application freezing and crashing?

Working with Microsoft .NET framework we have worked with threads through which we can handle all the tasks simultaneously under one main application thread. You can perform smaller operations with the help of Threading class, instead I prefer using Background Worker class to implement to perform all my heavy duty operations.
Background worker class is introduced in .NET framework 2.0 and using this class makes it easy to execute long running operations on a separate thread, support cancellation, progress reporting and marshalling results back to the UI thread.

Below image which provides an overview of background worker class which found here.

 

Now we will see how to use background worker class to perform heavy operations.

First create a new windows application as shown below.

 

Get to the design mode and drag & drop the background worker component.

Set the properties of the background worker:

Set GenerateMember and Modifiers as it is. In the sample application we have a progress bar which reports the percentage of the task completed so we need to set the WorkerReportsProgress to true and similarly if we want the user to cancel the running operation then set the WorkerSupportsCancellation to true.

Now the next step is to create 3 methods:

1.) DoWork: This is the main method which is responsible to handle the large operation. The code here is not different than the usual code.
2.) ProgressChanged: This method reports the change in the progress of the operation performed by the background worker DoWork method.
3.) RunWorkerCompleted: This method checks the RunWorkerCompletedEventArgs and perform action accordingly.

So how do we code these methods? It’s easy and not a complex task as it sounds, so let’s have a look at these methods….

To carry on with this example, I am using an AventureWorks database I have query the table Person.Contact as it has a large number of records, around 19K. Now here, to set the progress bar you first need to set the maximum property of the progress bar so we can show the progress completed.

Starting with the Start button:

private void btn_start_Click(object sender, EventArgs e)
{
//Starts the backgroundworker process asynchronously
bgw.RunWorkerAsync(); 
btn_start.Enabled = false;
}

The DoWork method:

//Background worker DoWork method. Here we will perform our heavy duty tasks.
//I have used a simple datareader object to traverse all the rows in the table. 
//The table has around 19K rows.
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
  try
  {
	int i = 0;
	cmd = new SqlCommand("SELECT * FROM Person.Contact", con);
	con.Open();
	dr = cmd.ExecuteReader();
	while(dr.Read())
	{
		i = i + 1;
		//report to the backgroungworker progreechanged event of the background worker class
		bgw.ReportProgress(i);
		Thread.Sleep(1);
		//Called and check if the cancellation of the operation is pending. If returned true
		//DoWorkEventArgs object cancels the operation.
		if (bgw.CancellationPending)
		{
			e.Cancel = true;
			return;
		}
	}
   }
   catch (Exception x)
   {
	MessageBox.Show("An error occured while performing operation" + x);
   }
   finally
   {
	con.Close();
   }
}

The RunWorkerCompleted Method:

private void bgw_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
{
	if (e.Cancelled)
	{
		MessageBox.Show("Operation Cancelled");
		btn_start.Enabled = true;
	}
	else
	{
		MessageBox.Show("Operation Completed");
		btn_start.Enabled = true;
	}
}

The ProgressChanged Method:

private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
	//Report porogress bar change
	progress.Value = e.ProgressPercentage;
}

Ending up with the cancel button:

//To cancel async operation
private void btn_cancel_Click(object sender, EventArgs e)
{
	 //To cancel the asynchronous operation
	 bgw.CancelAsync();
	 progress.Value = 0;
	 btn_start.Enabled = true;
}

So when your application is traversing the records and suddenly you think that you should quit the job and work on other part of the application, just hit the cancel button and the large operation will get cancelled withoud any freezing and hanging of your application.

Download: BackgroundWorkerDemo.zip (43.69 kb)

Currently rated 4.8 by 17 people

Microsoft WMI Code Creator

27. October 2009 01:15

.NET Framework C# Utils 

The WMI Code Creator tool generates code that uses WMI to obtain management information or perform management tasks. You can use the tool to learn how to manage computers using WMI scripting and WMI .NET. The tool generates code that runs on the local computer, a remote computer, or a group of remote computers based on your selection from the Target Computer menu on the tool. You can also execute the generated code directly from the tool.

The tool is meant to help IT Professionals quickly create management scripts and to help developers learn WMI scripting and WMI .NET. The tool helps take the complexity out of writing code that uses WMI and helps developers and IT Professionals understand how powerful and useful WMI can be for managing computers.

Using the tool, you can query for management information such as the name and version of an operating system, how much free disk space is on a hard drive, or the state of a service. You can also use the tool to execute a method from a WMI class to perform a management task. For example, you can create code that executes the Create method of the Win32_Process class to create a new process such as Notepad or another executable. The tool also allows you to generate code to receive event notifications using WMI. For example, you can select to receive an event every time a process is started or stopped, or when a computer shuts down.

The tool also allows you to browse through the available WMI namespaces and classes on the local computer to find their descriptions, properties, methods, and qualifiers.

The code that creates the tool is also included in the download. The tool was created using WMI .NET, and the code for the tool can help developers understand how WMI .NET is used to create applications and manage information. Be sure to read the end-user license agreement that is included in the download.

The above overview and other technical details about Microsoft WMI Code Creator can be found here at Microsoft download center.

Download: WMICodeCreator.zip (121.38 kb)

 No Rating

Requesting delivery/read receipt from C# using MailMessage class

16. October 2009 15:38

.NET Framework C# 

Sending e-mail through code is easy, but how do we get to know that an e-mail that we send is delivered and read by the intended recipient. When we send e-mail through code we can request a delivery notification and read receipt from the receiver, similar to the way we do in outlook. But the problem is not every mail server supports this kind of request from the code. We set a mail header while sending mail from code which is then processed by the mail server and the sender of the mail gets the intended response. I have test the below code with Microsoft Exchange Server and it works perfectly fine. So let’s see what the code has:

First we need the namespace to use MailMessage class.

using System.Net;
using System.Net.Mail;

Initialize MailMessage class and set To, From, Subject and Body parameters

//create the mail message
MailMessage mail = new MailMessage();
//set the addresses
mail.From = new MailAddress("prashantmx@xyz.com"); mail.To.Add("ankur@abc.com"); //set the content mail.Subject = "This is an email"; mail.Body = "this is the body content of the email.";

Now we have to set the Header property of the mail message class to request read/delivery recipt. As usual I first want to get notified for the e-mail I have sent has been delivered or not and then I want to get notified when my e-mail has been read by the recipient. Here I have also commented the deprecated method which is used in the previous version of .NET framework.

//This method has been deprecated.
//mail.Headers.Add("Return-Receipt-To", "prashantmx@xyz.com");
//Use this if you need a delivery notification of an email. DeliveryNotificationOption is an //umeration and can be used to set the delivery notification on the following options:
//1. Delay
//2. Never
//3. None
//4. OnFailure
//5. OnSuccess
/You can use also use OnFailure enum with OnSuccess enum. If in case the e-mail fails to 
//delivered you'll get notification for both the cases
mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess;
//Add "Disposition-Notification-To" for Read receipt
mail.Headers.Add("Disposition-Notification-To", "");

When you set the headers for requesting delivery and read receipt, set the mail server and login credentials for the domain or for the e-mail service you use and then in the end call the Send method to send the e-mail.

//Set the SMTP server. You can also set the hostname instead of IP Address
SmtpClient smtp = new SmtpClient("192.168.1.5"); 
//Set the user network/domain credentials
NetworkCredential netCredit = new NetworkCredential("prashant@xyz.com", "pass#word1", "DOMAIN_NAME");
//Get SMTP to authenticate the credentials
smtp.Credentials = netCredit;
//Send the e-mail
smtp.Send(mail);

As I mentioned earlier also I have tested the above code with Exchange server only and it works perfectly. Here is the complete listing of the code :

static void ReadReceipts()
{
 //create the mail message
 MailMessage mail = new MailMessage();
 //set the addresses
 mail.From = new MailAddress("prashantmx@xyz.com");
 mail.To.Add("ankur@abc.com");
 //set the content
 mail.Subject = "This is an email";
 mail.Body = "this is the body content of the email.";
 //This method has been deprecated.
 //mail.Headers.Add("Return-Receipt-To", "prashantmx@xyz.com"); 
 //Use this if you need an delivery notification of an email.             //DeliveryNotificationOption is an enumeration
 //and can be used to set the delivery notification on the following options:
 //1. Delay
 //2. Never
 //3. None
 //4. OnFailure
 //5. OnSuccess
 //You can use also use OnFailure enum with OnSuccess enum. If in case the e-mail
 //fails to delivered you'll get notification for both the cases
 mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess;
 //Add "Disposition-Notification-To" for Read receipt
 mail.Headers.Add("Disposition-Notification-To", "");
 
 //Set the SMTP server. You can also set the hostname instead of IP Address
 SmtpClient smtp = new SmtpClient("192.168.1.5"); 
 //Set the user network/domain credentials
 NetworkCredential netCredit =             new NetworkCredential("prashant@xyz.com", "pass#word1", "DOMAIN_NAME");
         //Get SMTP to authenticate the credentials
 smtp.Credentials = netCredit;
 //Send the e-mail
 smtp.Send(mail);
}
Currently rated 4.2 by 11 people

.NET Framework 4.0 Poster

29. September 2009 15:30

.NET Framework Silverlight 

The new .NET Framework 4.0 poster in deepzoom.

Download PDF: PDC2008-NETFX4.zip (3.22 mb)

Currently rated 4.8 by 5 people

.NET Framework 4.0 Architecture

23. September 2009 15:51

.NET Framework Microsoft 

 No Rating

«1234»