Thursday, June 2, 2011

Background Worker Example - Filling dataset in separate thread - Part 2

In my previous article [BackgroundWorker Component Overview in Winforms - Part 1], I described the working of BackgroundWorker component in Winform Application. In this article, I will demonstrate how to use the BackgroundWorker component to run a time-consuming operation on a separate thread. Example fills the dataset in background thread and also shows progress-bar while method is running.

First I created a class which inherits from BackgroundWorker Class which contains following key elements:

  1. An Enum ActionType : which contains Enum of Actions to do in background. i.e. FillCustData, DownloadCustImgs, etc will be used in method OnDoWork
  2. A public variable DoWorkArgs of type Dictionary<String, Object> for passing Arguments in key, value pair to worker method.
  3. A public class ResultData which contains properties like ResultObject, MsgText, PassedArgs etc to pass information from worker thread to UI layer. So UI layer can know what happened during background and take action based on Result.
  4. A protected override void OnDoWork (DoWorkEventArgs e) method - a key method which is executed during in separate thread.
  5. A winform with Button to start process in background and progressbar component to show progress while method is executing in background.

Here is the code for custom APKWorker Class which inherits from BackgroundWorker Class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.ComponentModel;

namespace TemplateApp
{
    public class APKWorker : BackgroundWorker
    {
        private ActionType ActionName { get; set; }
        private DataTable dtResult = null;
        public Dictionary<String, Object> DoWorkArgs = new Dictionary<string, object>();
       
        public APKWorker()
        {
            this.WorkerReportsProgress = true;
            this.WorkerSupportsCancellation = false;
        }

        public APKWorker(ActionType ActionName) : this()
        {
            this.ActionName = ActionName;
        }

        protected override void OnDoWork(DoWorkEventArgs e)
        {
            switch (this.ActionName)
            {
                case ActionType.RegisterUser:
                    //Call to method RegisterUser()
                    break;
                case ActionType.Insert_Usage_Statistic:
                    //Call to method Insert_Usage_Statistic()
                    break;
                case ActionType.FillUsers:

                    int deptid = 0;
                    if (DoWorkArgs.Keys.Contains("deptid"))
                        deptid = (int)DoWorkArgs["deptid"];


                    dtResult = new DataTable();
                    dtResult.Columns.Add("UID", Type.GetType("System.Int32"));
                    dtResult.Columns.Add("UserName", Type.GetType("System.String"));
                    DataRow dr = null;
                    this.ReportProgress(30, "Started");
                    System.Threading.Thread.Sleep(2000);
                    for (int i = 0; i < 5; i++)
                    {
                        dr = dtResult.NewRow();
                        dr["UID"] = i;
                        dr["UserName"] = "Test" + i.ToString();
                        dtResult.Rows.Add(dr);
                    }
                    this.ReportProgress(80, "Data Filled");
                    System.Threading.Thread.Sleep(2000);
                    e.Result = new ResultData { PassedArgs = DoWorkArgs, MsgText = "Data Filled.", MsgType = ResultData.MessageType.Success, ResultObject = dtResult };
                    this.ReportProgress(100, "Completed");
                    break;
            }
            base.OnDoWork(e);
        }

        public enum ActionType
        {
            RegisterUser,
            Insert_Usage_Statistic,
            FillUsers
        }
    }

    public class ResultData
    {
        public Object ResultObject { get; set; }
        public string MsgText { get; set; }
        public MessageType MsgType { get; set; }
        public Dictionary<String, Object> PassedArgs { get; set; }

        public enum MessageType
        {
            Success,
            Failure
        }       
    }

}

Code to write in Winform for Calling background worker class:

        private void btnTest_Click(object sender, EventArgs e)
        {
            this.progressBar1.Minimum = 0;
            this.progressBar1.Maximum = 100;
            APKWorker objWorker = new APKWorker(APKWorker.ActionType.FillUsers);
            objWorker.DoWorkArgs.Add("userid", 10);
            objWorker.DoWorkArgs.Add("deptid", 3);
            objWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(objWorker_RunWorkerCompleted);
            objWorker.ProgressChanged += new ProgressChangedEventHandler(objWorker_ProgressChanged);
            objWorker.RunWorkerAsync();

        //Implementation Example 2:
        //APKWorker objWorker = new APKWorker();
        //objWorker.DoWork += new DoWorkEventHandler(objWorker_DoWork);
        //objWorker.RunWorkerAsync();
        //void objWorker_DoWork(object sender, DoWorkEventArgs e)
        //{
        //    MessageBox.Show("hello");
        //}
        //Above example is useful, if you need to implement some custom logic in DoWork method. Here, first don't pass Actionname from Constructor,
        //then add the 2nd line - objWorker.DoWork += new DoWorkEventHandler(objWorker_DoWork); and write custom logic in objWorker_DoWork
        }       

        void objWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.progressBar1.Value = e.ProgressPercentage;
            this.lblMsg.Text = (string)e.UserState;
        }

        void objWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            ResultData ResultObj = (ResultData)e.Result;
            DataTable dtUser = (DataTable)ResultObj.ResultObject;
            MessageBox.Show(ResultObj.PassedArgs["deptid"].ToString());
            MessageBox.Show(dtUser.Rows[2]["UserName"].ToString());
            MessageBox.Show("Done");
        }


Hope this example will help to all who wants to use Background worker class to run long running methods in separate thread. Feel free to post your comments.

Background Worker Overview with Example in Winforms - Part 1

Recently, while working on Winform Application, we require certain time consuming tasks on Form load to run in separate Thread. We decided to use Background Worker Component in our application. However, there is need that Background Component will be used in multiple forms. So I decided to create a class which inherits from BackgroundWorker Class and implemented certain common functionality over there. I like to share the code and overview of Background worker class.

BackgroundWorker Component Overview:

The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like
  •     Image downloads
  •     Web service invocations
  •     File downloads and uploads (including for peer-to-peer applications)
  •     Complex local computations
  •     Database transactions
  •     Local disk access
can cause your user interface to hang while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker component provides a convenient solution.

The BackgroundWorker component gives you the ability to execute time-consuming operations asynchronously ("in the background"), on a thread different from your application's main UI thread.

To use a BackgroundWorker, you simply tell it what time-consuming worker method to execute in the background, and then you call the RunWorkerAsync method. Your calling thread continues to run normally while the worker method runs asynchronously. When the method is finished, the BackgroundWorker alerts the calling thread by firing the RunWorkerCompleted event, which optionally contains the results of the operation.

The BackgroundWorker component is available from the Toolbox, in the Components tab. To add a BackgroundWorker to your form, drag the BackgroundWorker component onto your form. It appears in the component tray, and its properties appear in the Properties window.

By using a pattern of method calls (RunWorkerAsync, ReportProgress) and event callbacks (DoWork, ProgressChanged, RunWorkerCompleted), BackgroundWorker helps you easily create a background thread and factor out the stuff that should be running on the background thread versus the foreground thread. 

If your background operation requires a parameter, call RunWorkerAsync with your parameter. Inside the DoWork event handler, you can extract the parameter from the DoWorkEventArgs.Argument property. 

Below image shows the flow of working of Background Worker model.


Above is the brief overview of how Background worker class works and what are its key events and methods. In the next article [Background worker example - Filling dataset in separate thread - Part 2], I explained working of Background worker class with code, which fills the Dataset in background and also shows the progress-bar while running the process in background.

Saturday, February 26, 2011

Simple Tips for Healthy Living for Software Engineers

Simple tips for healthy living for Software Engineers

This tips are specially for Software Engineers who usually sits for 8-10 hours a day in front of computers solving complex problems of world and have no time to take care of health. One can minimize ill effects of stress and stay healthy by following a few simple tips as below.

1. Get adequate sleep:

Remember that not getting enough sleep will do you harm in the long run. you will feel drowsy during the day, unable to concentrate on simple tasks and feel irritable. Try to get at least seven hours of sleep every day. Avoid keeping Televisions, Computer and gadgets in your bedroom, don’t eat large meals before bedtime, follow regular bedtimes and wake times. Ensure your bedroom is quite and relaxing.

2. Drink Hot Water:

While it may take a little while to get used to having hot water; it will greatly benefit you. It purifies your body and helps remove unwanted properties as well. Your digestive system will work smoothly and also clear out your skin.

3. Spend lesser time on Social Networking Sites:

Researchers say that an increasingly high number of people prefer to spend time surfing the internet and spending time on social networking sites instead of pursuing a hobby. Ask yourself how much time you spend on networking sites every week and whether it is worth it. Opt for a hobby, which will give you a chance to enjoy, learn something new and meet new people.

4. Exercise:

You don’t need to pump iron six days a week in a gym to stay in shape. A brisk walk for 30 minutes every day in your neighborhood will do you a whole lot of good. Do a few simple stretches and exercises every alternate day at home or alternatively start doing yoga and meditation. Walking, cycling, swimming or even dancing are great stress busters and also keep you in shape.

5. Quit Smoking:

If you have finally made up your mind to kick this habit, it’s really good for your health. To quit successfully you need encouragement and support from your doctor, family, friends, and coworkers. A doctor will help you tailor an approach that suits you best.

6. Follow a healthy diet:

Try eating a whole grain sandwich before your big meal, eat smaller portions of high calorie dishes, ask yourself if you’re an emotional eater, and avoid reaching out for snacks while watching TV. Include more vegetables and fruits in your daily diet. If you're trying to loose weight, don't starve yourself.

7. Blink your eyes at regular interval:

Follow the 20-20-20 rule. After every 20 minutes of work, look 20 feet away from the computer screen and blink 20 times. Also lubricate your eyes at regular interval to avoid dryness of eyes. Use lubricating eye drops in both the eyes before every session on the computer. Consult your eye surgeon before using any eye drops.


Wednesday, January 19, 2011

Multiple Active Result Sets (MARS) in SQL Server

Before few days, one of my colleague came with one issue - he was getting error while opening multiple DataReader with single Connection object i.e. he is trying to open 2nd datareader with same connection object in Loop. And he got error - There is already an open DataReader associated with this Command which must be closed first. I search and get way to open multiple DataReader connections with SQLServer and like to share with all.

Sql Server supports MARS (Multiple Active Result Sets) and we need to set MultipleActiveResultSets=true in connection string. Below is Connection string syntax and Code to demonstrate opening datareader in while loop (multiple datareader). MARS is supported from SQL Server 2005 Version.

Connection String:

<add name ="DBConnstr" connectionString ="Data Source=xxx.yyy.zzz.aa;Initial Catalog=name;User Id=id;Integrated Security=False;Password=pwd;MultipleActiveResultSets=true"  providerName ="System.Data.SqlClient" />

Code:

string strConn = ConfigurationManager.ConnectionStrings["DBConnstr"].ConnectionString;
string strSql = "select * From OrderDetail where OrderID = {0}";
string strOutput = "OrdNumber: {0} - Desc: {1}";

using (SqlConnection con = new SqlConnection(strConn))
{
 //Opening Connection   
 con.Open();

 //Creating two commands form current connection   
 SqlCommand cmd1 = con.CreateCommand();
 SqlCommand cmd2 = con.CreateCommand();

 //Set the comment type   
 cmd1.CommandType = CommandType.Text;
 cmd2.CommandType = CommandType.Text;

 //Setting the command text to first command   
 cmd1.CommandText = "select OrderID From [OrderMaster]";

 //Execute the first command   
 IDataReader idr1 = cmd1.ExecuteReader();
 while (idr1.Read())
 {
  //Read the first Tree value from data source       
  int intTree = Convert.ToInt32(idr1.GetInt16(0));

  //create another command, which get values based on Tree value       
  cmd2.CommandText = string.Format(strSql, intTree);

  //Execute the reader       
  IDataReader idr2 = cmd2.ExecuteReader(); // If MARS is not enable in Conn string ; error will come at this line.
  while (idr2.Read())
  {
   //Read the values from Reader 2
   Console.WriteLine(string.Format(strOutput, idr2.GetString(1), idr2.GetString(4)));
  }
  //Dont forgot to close second reader, this will just close reader not connection       
  idr2.Close();
 }
 idr1.Close();
}




Friday, November 12, 2010

DayLight Saving and DateTime in .Net

Today, while looking to solve one issue related to DataTime in .Net, I came across article from MSDN that describes the best practice recommendations for writing programs that use the DateTime type in Microsoft .NET-based applications and assemblies.

While going through article, I came across the Daylight saving time (DST) and its impact on Applications. So I decided to give brief about DST and will discuss how it effects the Programmers.

Daylight saving time:

Daylight saving time (DST)—also summer time in British English is the practice of temporarily advancing clocks during the summer time so that afternoons have more daylight and mornings have less. Typically clocks are adjusted forward one hour near the start of spring and are adjusted backward in autumn.

In a typical case where a one-hour shift occurs at 02:00 local time, in spring the clock jumps forward from 02:00 standard time to 03:00 DST and that day has 23 hours, whereas in autumn the clock jumps backward from 02:00 DST to 01:00 standard time, repeating that hour, and that day has 25 hours.

A digital display of local time does not read 02:00 exactly at the shift, but instead jumps from 01:59:59.9 either forward to 03:00:00.0 or backward to 01:00:00.0. Clock shifts are usually scheduled near a weekend midnight to lessen disruption to weekday schedules.

Advantages of DST:
  • Many countries observe DST, and many do not. The reason many countries implement DST is in hopes to make better use of the daylight in the evenings.
  • Some believe that it could be linked to reducing the amount of road accidents and injuries.
  • The extra hour of daylight in the evening is said to give children more social time with friends and family
  • DST can even boost the tourism industry because it increases the amount of outdoor activities.
  • Majority of people also believe that DST saves energy as it influences people to spend more time out of the house, thus decreasing the need for artificial lighting as well as the likelihood of using home electric appliances.

Disadvantages of DST:
  • Flight schedules and inaccurate transportation timetables have caused confusion among travelers, for both personal and business purposes, and regular commuters. The transport industry needed to take into account the costs for adjusting to new time schedules.
  • Other complaints about daylight saving include the safety fears in the dark mornings, especially for school children waiting for a bus in some areas. Those who went early to work or study, they would be leaving their homes in the dark, the time when crime was at its highest, putting them in potentially dangerous situations.
  • Farming groups have also expressed anti-daylight saving views, saying that daylight saving time had a significant adverse impact on rural families, businesses, and communities. There are also those who express health concerns linked with daylight saving time.

Daylight Saving Time and .Net:

Consider a case when on particular morning during DST, at 2:00 AM, the local clock is reset to 1:00 AM, creating a 25-hour day. Since all values of clock time between 1:00 AM and 2:00 AM occur twice on that particular morning—at least in most of the United states and Canada. The computer really has no way to know which 1:10 AM was meant—the one that occurs prior to the switch, or the one that occurs 10 minutes after the daylight savings time switch.

Similarly, programs have to deal with the problem that happens in the springtime when, on a particular morning, there is no such time as 2:10 AM. The reason is that at 2:00 on that particular morning, the time on local clocks suddenly changes to 3:00 AM. The entire 2:00 hour never happens on this 23-hour day.

Programs have to deal with these cases (Particularly applications that deals with Scheduler. Such as Marketing Emails to send during night hours or taking Backup during night), possibly by prompting the user when you detect the ambiguity. 

If you aren't collecting date-time strings from users and parsing them, then you probably don't have these issues. Programs that need to determine whether a particular time falls in daylight savings time can make use of the following:
    Timezone.CurrentTimeZone.IsDaylightSavingTime(DateTimeInstance)
or
DateTimeInstance.IsDaylightSavingTime
   
So, if you need to perform DateTime calculations (add/subtract) on values representing time zones that practice daylight savings time, unexpected calculation errors can result. Instead, convert the local time value to universal time, perform the calculation, and convert back to achieve maximum accuracy.

For the complete tips for dealing with DateTime, go through the below link from MSDN.

http://msdn.microsoft.com/en-us/library/ms973825.aspx

I believe that above link from MSDN is helpful to all the Programmers. If we take care of above points, our software are least prone to errors.


For further details on DST:
http://www.timeanddate.com/time/dst/