this blog contains information for .net and sql stuffs. You can find various tips and tricks to overcome problem you may be facing in ...

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

Friday, May 7, 2010

Threading in .net (Part -2)

In previous post, we have got idea of what is threading and how it can be done easily by calling ThreadPool.QueueUserWorkItem. But threading is not that mean only we need more control on our threading activity.

Like we need to ensure that all thread must work, give priority to my thread than other once, weather my thread has been completed or not, what is status of my thread etc.. all thing can be done by various type of mechanism provided by .net. Yes it’s surely a tedious and complex task to implement but if we do it carefully it not only reduces response time but application behaves very nicely and manages resources.

ThreadPool.QueueUserWorkItem provides a way to run thread in back ground and let it run until it finish. For more control on thread we can create instance of thread, we can even control start, pause, abort, priority. We can handle ThreadAbortException when thread has been aborted.

àCreate thread instance

Thread myThread = new Thread(new ThreadStart(myWork));

àStart thread

myThread.Start();

àWait for some time to run myThread

Thread.Sleep(2000);

àAbort myThread

myThread.Abort();

myWork method has following implementation

public static void myWork()

{

Console.WriteLine("myWork is running on another thread.");

try

{

Thread.Sleep(5000);

}

catch (ThreadAbortException ex)

{

Console.WriteLine("myWork was aborted.");

}

finally

{

Console.WriteLine("Use finally to close all open resources.");

}

Console.WriteLine("myWork has ended.");

}

In above code “myWork has ended” will never display as I have aborted thread. If I comment that line that it will be displayed.

We can call Thread.Suspend and Thread.Resume to stop and resume thread execution but sometime they can create problem. Say for example I am stopping a thread which has acquired my printer, so it will create deadlock condition as my other thread may need printer.

We can set thread priority before starting thread by ThreadPriority enumeration. Enumeration has following values.

àHighest

àAboveNormal

àNormal

àBelowNormal

àLowest

By default foreground and background run on normal priority.

Thread’s state can be checked with Thread.ThreadState property. There are various types of it like Unstarted, Running, Stopped, Suspended, Aborted etc. At a time a thread may have one or more thread state.

Sometime there is requirement to know status of thread which is running in background we want to pass some data to thread and let us know what is the output of that data after certain time elapsed. We can achieve this task by creating delegate and callback. For that we need to create a delegate at class level and a method to handle that delegate. Create a class for which you want to run in background, add delegate to class. Create an instance of class and in constructor pass delegate with appropriate method.

When there are more than one thread runs simultaneously, situation may happen it acquires resource and in turn deadlock. So it means instead of improvement in performance our application become slow and unresponsive. At that time we need to manage resource by synchronizing thread resource.

Use lock keyword in C# and SynLock keyword in vb.net. It does not allow using resource of any other thread till it completes it work. One thing should be kept in mind that these keywords work only with reference type not on value type.

When there is requirement of separate read and write lock on resource we can use ReaderWriterLock class. Create instance of this class and use separate read and write lock.

ReaderWriterLock rwl = new ReaderWriterLock()

To acquire read lock

rwl.AcquireReaderLock(10000);

Release reader lock

rwl.ReleaseReaderLock();

Acquire writer lock and release it.

rwl.AcquireWriterLock(10000);

rwl.ReleaseWriterLock();

Another method to synchronize thread is to use object of Interlocked class. It will add numeric value to thread. It also provides various numeric methods.

There are also so many things to wait for thread to complete and start another thread once complete previous one.

NOTE: In visual basic we need to add attribute to main method to run main thread as multithread. MTA (Multithread Apartment) is by default provided in C#, so there is no need to add it. MTA supports calling WaitHandle.WaitAll.

Thursday, May 6, 2010

Threading in .net (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 require.

To work with thread we need to add System.Threading namespace to our application. We can run background thread by using ThreadPool.QueueUserWorkItem and passing method name or address of in vb.net.

static void Main(string[] args)

{

int workerThreads;

int completionPortThreads;

ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);

ThreadPool.QueueUserWorkItem(ThreadProc, "Thread 1");

ThreadPool.QueueUserWorkItem(ThreadProc, "Thread 2");

ThreadPool.QueueUserWorkItem(ThreadProc, "Thread 3");

ThreadPool.QueueUserWorkItem(ThreadProc, "Thread 4");

ThreadProc("ForgroundThread");

Thread.Sleep(1000);

Console.WriteLine("Worker Threads: {0} CompletePortThreads: {1}", workerThreads, completionPortThreads);

ThreadPool.QueueUserWorkItem(ThreadProc, "Thread 5");

ThreadPool.QueueUserWorkItem(ThreadProc, "Thread 6");

Console.WriteLine("Now main is continue");

}

Above code shows how many threads can be run, default value is 250. We have used ThreadProc method which will run in background thread. When main thread has no work at that time background thread will run and execute code. We can add as many threads as we wish as per limit of 250 and if required we can increase this maximum thread limit.

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.