Showing posts with label Threading. Show all posts
Showing posts with label Threading. Show all posts

Monday, February 14, 2011

Threading Part - 2


This post is in continuation with Threading Part - 1....

In first post, we have seen the basic understanding on the Threading and its usage.
Now, let us consider comparatively complex scenarios....

Using Thread.Join
More often than not, you will need your application to wait for a thread to complete
execution. To accomplish this, the Thread class supports the Join method:

// C#
theThread.Join();

The Join method tells the system to make your application wait until the thread has
completed. Of course, in this simple case you do not really need a second thread
because you are just waiting for it to complete anyway. A better example is for us to
have five threads that all do some work and to wait for them. When we are working
with multiple threads, our programming task is a bit more complicated, as we need to
wait for all our threads. We can do this by keeping a reference to all our threads and calling Join on each of the threads to wait for the threads to complete, one at a time,as demonstrated in the following code:

// C#
ThreadStart operation = new ThreadStart(SomeWork);
Thread[] theThreads = new Thread[5];
for (i nt x = 0; x < 5; ++x)
{
// Creates, but does not start, a new thread
theThreads[x] = new Thread(operation);
// Starts the work on a new thread
theThreads[x].Start() ;
}
// Wai t for each thread to complete
foreach (Thread t in theThreads)
{
t.Join();
}
By storing the threads in an array, we can wait for each of the Threads one at a time. As each thread completes, the Join method will return and we can continue.

Thread Priority
The Thread class supports the setting or getting of the priority of a thread using the ThreadPriority enumeration.

  1. Highest - The highest priority
  2. AboveNormal - Higher priority than Normal
  3. Normal - The default priority
  4. BelowNormal - Lower than Normal
  5. Lowest - The lowest priority



Threads are scheduled based on this enumeration. In most cases, you will want to use
the default (Normal). Deciding to use threads that have lower thread priority can
cause the operation system to starve a thread more than you might expect, or if you
use higher priorities (especially Highest), you can starve the system. Although it is necessary to use non-Normal thread priorities at times, make this decision with much caution. Increasing the performance of a system simply by increasing thread priority is not likely to help in the long term, as other starved threads tend to back up and cause unexpected consequences.

Passing Data to Threads
In each of the earlier examples, we were using the ThreadStart delegate, which takes
no parameters. In most real-world use of threading, you will need to pass information
to individual threads. To do this, you need to use a new delegate called ParameterizedThreadStart. This delegate specifies a method signature with a single parameter of type Object and returns nothing. The following code snippet provides an example:

// C#
static void WorkWithParameter(object o)
{
string i nfo = (string) o;
for (int x = 0; x < 10; ++x)
{
Console. WriteLine("{0}: {1}", i nfo,
Thread.CurrentThread.ManagedThreadId);
// Slow down thread and let other threads work
Thread. Sleep(10);
}
}

This is a method that takes a single Object parameter (and therefore can be a reference to any object). To use this as the starting point of a thread call, you can create a ParameterizedThreadStart delegate to point at this new method and use the Thread.Start method’s overload that takes a single object parameter. The following code snippet provides an example:

// C#
ParameterizedThreadStart operation = new ParameterizedThreadStart(WorkWithParameter);
// Creates, but does not start, a new thread
Thread theThread = new Thread(operation);
// Starts the work on a new thread
theThread.Start("Hel l o");
// A Second Thread wi th a different parameter
Thread newThread = new Thread(operation);
newThread.Start("Goodbye");

Be aware that because the WorkWithParameter method takes an object, Thread. Start
could be called with any object instead of the string it expects. Being careful in choosing your starting method for a thread to deal with unknown types is crucial to good threading code. Instead of blindly casting the method parameter into our string, it is a better practice to test the type of the object, as shown in the following example:
// C#
string i nfo = o as string;
if (info == null )
{
throw Invali dProgramException("Parameter for thread must be a string");
}

Threading Part - 1


Most of the time developer chooses to develop program in linear way. In this mechanism user would need to wait sometime in some situation like application is going to download page from server, application is going to print document, applications is going to access remote database. Those cases are time consuming, user needs to wait till main thread completes work, sometime user get frustrated by response time, and application does not response to user till task has been completed.
To overcome, .net has provided threading mechanism. Our main thread executes as and in background we can execute process. So user will not feel that application is not responding, in background thread method executes and once result will be available, it would be shown to user.

Threading means in a single process execute more than one task among different processors. Now days most of computers are more than one core, we can use another core when main core is busy to complete task. We can distribute work task among different processors.

Though multithreading seems to be very complex, .net has provided a simple way to implement in programming. At a time there can be more than 250 threads run in back ground. We can even change it to more if required.

To work with thread we need to add System.Threading namespace to our application.

Creating a Thread
To create and start a new thread, follow these steps:
1. Create a method that takes no arguments and does not return any data (for example, use the void return type for C#). This method should look something like this:

// C#
static void SimpleWork()
{
Console. WriteLine("Thread: {0}", Thread. CurrentThread. ManagedThreadId);
}
2. Create a new ThreadStart delegate, and specify the method created in step 1.
3. Create a new Thread object, specifying the ThreadStart obj ect created in step 2.
4. Call Thread.Start to begin execution of the new thread.
Your code will end up looking something like this:

// C#
ThreadStart operation = new ThreadStart(SimpleWork);
// Creates, but does not start, a new thread
Thread theThread = new Thread(operation);
// Starts the work on a new thread
theThread.Start();

When the Start method is called, the SomeWork method is called on a new thread and
the thread executes until the method completes. In this example, our SimpleWork
method writes the phrase “In Thread” and shows the ManagedThreadId property. This
property is a numeric number assigned to every thread.

Using Multiple Threads
A more likely scenario than this simple case is one in which you’ll want to create
multiple threads to do work. For example, we can change the example just shown to
create multiple threads and start them all on the same work:
// C#
ThreadStart operation = new ThreadStart(SimpleWork);
for (i nt x = 1; x <= 5; ++x)
{
// Creates, but does not start, a new thread
Thread theThread = new Thread(operation);
// Starts the work on a new thread
theThread.Start();
}

This executes the work on five separate threads, as concurrently as your particular
machine is capable of doing. If we implement this change, we should get five separate
threads all writing out their own thread ID to the console window:
Thread: 3
Thread: 4
Thread: 5
Thread: 6
Thread: 7

We see consecutive thread numbers because the work we are doing in SimpleWork is
very quick. Let’s change our work to something a little more lengthy so that we can
see the threads working concurrently:

// C#
static void Simpl eWork()
{
for (int x = 1; x <= 10; ++x)
{
Console. WriteLine("Thread: {0}",
Thread.CurrentThread.ManagedThreadId);
// Sl ow down thread and let other threads work
Thread.Sl eep(10);
}
}

In this new version of SimpleWork, we are writing out our thread identifier 10 times.
In addition, we are using Thread.Sleep to slow down our execution. The Thread.Sleep
method allows us to specify a time in milliseconds to let other threads perform work.
On every thread, we are allowing 10 milliseconds for the other threads to write their
own data to the console. To see how this works, we can change our SimpleWork method to write out the iteration it is working on:

Thread: 3
Thread: 4
Thread: 5
Thread: 6
Thread: 7
Thread: 3
Thread: 4
Thread: 5
Thread: 6
Thread: 7

Doing this allows us to perform operations as concurrently as our hardware will
allow. As our work increases and the time it takes to complete each thread becomes longer, we will need to determine how to make our main thread (the one that the thread creation code exists on) wait until all the work is complete. This is where the Thread.Join method comes in.


Thread which runs first is called Forground and other called background.

static void ThreadProc(object msg)
{
string threadMsg = (string)msg;
if (Thread.CurrentThread.IsBackground)
{
Console.WriteLine(“Background Thread”);
Console.WriteLine(“My Threading method with:” + threadMsg);
}
else
{
Console.WriteLine(“Forground Thread”);
Console.WriteLine(“My Threading method with:” + threadMsg);
}
}
We can check weather thread is background or not with Thread.CurrentThread.IsBackGround property.
Some time threading also overheads on processors, so need to take care while implementing threading as it distribute loads to different processor, more memory is required to manage resource.
Wise use of threading may improve application’s performance. It depends on requirement and application problem to use of Threading.

Wednesday, February 2, 2011

Microsoft Community Contritor Award 2011


I would like to take opportunity to thank all readers for making my blogs successful and I have been awarded as Microsoft Community Contributor Award 2011. I thanks Microsoft for providing such honour to me and also thanks all my friends who are marking my posts as Answers and blog readers.......




The begining of year 2011 has been very successful for me. I believe this award as achievement in life and may this year will bring success to all of you. I would like to tell all my friends and readers to start blogging. I have seen quite intelligent IT Professionals and Excepectional Developers are not blogging....I would like to encourage them to start blogging immediately because unless and until you don’t blog community will not know what you are doing.

My Msdn Profile

Thanks,
Have happy blogging and programming

Tuesday, August 3, 2010

Asynchronous Programming Techniques

You will often have to create applications that perform time-consuming operations, such as fi le downloads or complex calculations. These operations can cause the user interface (UI) to lock up and become unresponsive, leading to an unpleasant user experience. By using asynchronous programming techniques, you can enable time-consuming operations to be run asynchronously, thus keeping the UI responsive while the operations are run.

You are frequently required to perform tasks that consume fairly large amounts of time, such as file downloads. The BackgroundWorker component provides an easy way to run timeconsuming processes in the background, thereby leaving the UI responsive and available for user input.

The BackgroundWorker component is designed to allow you to execute time-consuming
operations on a separate, dedicated thread. This allows you to run operations that take a lot of time, such as fi le downloads and database transactions, asynchronously and allow the UI to remain responsive.
The key method of the BackgroundWorker component is the RunWorkerAsync method.
When this method is called, the BackgroundWorker component raises the DoWork event. The code in the DoWork event handler is executed on a separate, dedicated thread, allowing the UI to remain responsive. Important members of the BackgroundWorker component are shown below:
1. CancellationPending Property - Indicates whether the application has requested cancellation of a background operation.
2. IsBusy Property - Indicates whether the BackgroundWorker is currently
running an asynchronous operation.
3. WorkerReportsProgress Property - Indicates whether the BackgroundWorker component can report progress updates.
4. WorkerSupportsCancellation Property - Indicates whether the BackgroundWorker component supports asynchronous cancellation.
5. CancelAsync Method - Requests cancellation of a pending background operation.
6. ReportProgress Method - Raises the ProgressChanged event.
7. RunWorkerAsync Method - Starts the execution of a background operation by
raising the DoWork event.
8. DoWork Event - Occurs when the RunWorkerAsync method is called. Code in the DoWork event handler is run on a separate and dedicated thread.
9. ProgressChanged Event - Occurs when ReportProgress is called.
10. RunWorkerCompleted Event - Occurs when the background operation has been completed or cancelled or has raised an exception.


Running a Background Process :
The RunWorkerAsync method of the BackgroundWorker component starts the execution of
the background process by raising the DoWork event. The code in the DoWork event handler
is executed on a separate thread. The following procedure explains how to create a background
process.
TO CREATE A BACKGROUND PROCESS WITH THE BACKGROUNDWORKER COMPONENT :
1. From the Toolbox, drag a BackgroundWorker component onto the form.




2. In the component tray, double-click the BackgroundWorker component to create the
default event handler for the DoWork event. Add the code that you want to run on the
separate thread. An example is shown below.
// C#
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Insert time-consuming operation here
}
3. Elsewhere in your code, start the time-consuming operation on a separate thread by
calling the RunWorkerAsync method, as shown:
// C#
backgroundWorker1.RunWorkerAsync();


Providing Parameters to the Background Process:
Sometimes you will want to run a background process that requires a parameter. For example,you might want to provide the address of a fi le for download. You can provide a parameter in the RunWorkerAsync method. This parameter will be available as the Argument property of the instance of DoWorkEventArgs in the DoWork event handler.

TO PROVIDE A PARAMETER TO A BACKGROUND PROCESS :
1. Include the parameter in the RunWorkerAsync call, as shown below:
// C#
backgroundWorker1.RunWorkerAsync("C:\\myfile.txt");
2. Retrieve the parameter from the DoWorkEventArgs.Argument property and cast it
appropriately to use it in the background process. An example is shown below:
// C#
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string myPath;
myPath = (string)e.Argument;
// Use the argument in the process
RunTimeConsumingProcess();
}

Announcing the Completion of a Background Process :
When the background process terminates, whether because the process is completed or
the process is cancelled, the RunWorkerCompleted event is raised. You can alert the user to the completion of a background process by handling the RunWorkerCompleted event. An example is shown below:


// C#
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
System. Windows.Forms.MessageBox.Show("Background process completed");
}

You can ascertain if the background process was cancelled by reading the e.Cancelled
property, as shown below:
// C#
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
System. Windows.Forms.MessageBox.Show ("Process was cancelled!");
}
else
{
System. Windows.Forms.MessageBox.Show("Process completed");
}
}

RETURNING A VALUE FROM A BACKGROUND PROCESS :
You might want to return a value from a background process. For example, if your process
is a complex calculation, you would want to return the end result. You can return a value by
setting the Result property of the DoWorkEventArgs in the DoWorkEventHandler. This value
will then be available in the RunWorkerCompleted event handler as the Result property of the
RunWorkerCompletedEventArgs parameter, as shown in the following example:
// C#
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Assigns the return value of a method named ComplexCalculation to
// e.Result
e.Result = ComplexCalculation();
}
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
System. Windows.Forms.MessageBox.Show("The result is " +
e.Result.ToString());
}

Cancelling a Background Process :
You might want to implement the ability to cancel a background process. Background-
Worker supports the ability to cancel a background process, but you must implement most of the cancellation code yourself. The WorkerSupportsCancellation property of the Background Worker component indicates whether the component supports cancellation. You can call the CancelAsync method to attempt to cancel the operation; doing so sets the CancellationPending property of the BackgroundWorker component to True. By polling the CancellationPending property of the BackgroundWorker component, you can determine whether or not to cancel the operation.

TO IMPLEMENT CANCELLATION FOR A BACKGROUND PROCESS :
1. In the Properties window, set the WorkerSupportsCancellation property to True to
enable the BackgroundWorker component to support cancellation.
2. Create a method that is called to cancel the background operation. The following
example demonstrates how to cancel a background operation in a Button.Click event
handler:
// C#
private void btnCancel_Click(object sender, EventArgs e)
{
backgroundWorker1.CancelAsync();
}
3. In the BackgroundWorker.DoWork event handler, poll the BackgroundWorker.CancellationPending
property and implement code to cancel the operation if it is True. You
should also set the e.Cancel property to True, as shown in the following example:
// C#
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <>

if (backgroundWorker1.CancellationPending)

{

e.Cancel = true; return;

}

}

}



Reporting Progress of a Background Process with BackgroundWorker:
For particularly time-consuming operations, you might want to report progress back to the primary thread. You can report progress of the background process by calling the Report- Progress method. This method raises the BackgroundWorker.ProgressChanged event and allows you to pass a parameter that indicates the percentage of progress that has been completed to the methods that handle that event. The following example demonstrates how to call the ReportProgress method from within the BackgroundWorker.DoWork event handler and then to update a ProgressBar control in the BackgroundWorker.ProgressChanged event handler:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1;i <>

{ RunTimeConsumingProcess();

// Calls the Report Progress method, indicating the percentage

// complete

backgroundWorker1.ReportProgress(i*10);

}

}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)

{

progressBar1.Value = e.ProgressPercentage;

}

Note that in order to report progress with the BackgroundWorker component you must set the WorkerReportsProgress property to True.

Thanks,

Paras Sanghani