Saturday, March 1, 2008

Multithreading in VB.NET

Multithreading gives programs the ability to do several things at a time. Each stream of execution is called a thread. Multithreading is used to divide lengthy tasks into different segments that would otherwise abort programs. Threads are mainly used to utilize the processor to a maximum extent by avoiding it's idle time. Threading lets a program seem as if it is executing several tasks at once. What actually happens is, the time gets divided by the computer into parts and when a new thread starts, that thread gets a portion of the divided time. Threads in VB .NET are based on the namespace System.Threading.


Introduction.

Multithreading is new to VB developer, VB developer always wanted this feature in the language and its there in VB .NET.

One of the many great features in Windows 95 and Windows NT is multiple threads. The power of multithreaded programming requires responsible programming. It's up to you to ensure that the CPU switching between threads won't cause bad things to happen. For example, you might have data (such as a linked list) that can be accessed by more than one thread. Your code needs to ensure that a threads switch at the wrong moment won't leave your data in an inconsistent state. You prevent threads-switching problems by using synchronization objects.

Threading.

One or more threads run in an AppDomain. An AppDomain is a runtime representation of a logical process within a physical process. A thread is the basic unit to which the operating system allocates processor time. Each AppDomain is started with a single thread, but can create additional threads from any of its threads.

Each thread maintains exception handlers, a scheduling priority, and a set of structures the system will use to save the thread context until it is scheduled. The thread context includes the thread's set of machine registers and stack, in the address space of the thread's process.

Operating systems that support preemptive multitasking create the effect of simultaneous execution of multiple threads from multiple processes. On a multiprocessor computer, some operating systems that are multi-processor aware can simultaneously execute as many threads as there are processors on the computer.

A multitasking operating system divides the available processor time among the processes or threads that need it. The system is designed for preemptive multitasking; it allocates a processor time slice to each thread it executes. The currently executing thread is suspended when its time slice elapses, allowing another thread to run. When the system switches from one thread to another, it saves the thread context of the preempted thread and restores the saved thread context of the next thread in the queue.

Synchronization.

Synchronizing resource access between threads is a common problem when writing multithreaded applications. Having two or more threads simultaneously access the same data can lead to undesirable and unpredictable results. For example, one thread could be updating the contents of a structure while another thread is reading the contents of the same structure. It is unknown what data the reading thread will receive: the old data, the newly written data, or possibly a mixture of both. .NET provides a number of synchronization and synchronization access classes to aid in solving this problem.

This article explains the Monitor class available and how to use them to create thread-safe classes in a typical multithreaded application.

Monitors.

Monitors are associated with an object on demand.
Monitors are unbound i.e. can be called directly from any Context.
Monitors cannot be instantiated; they are associated with an object.
Monitors expose the ability to take and release the sync block lock on an object on demand via Enter, TryEnter and Exit. The Monitor Wait, Pulse and PulseAll methods are related to SyncBlocks. It is necessary to be in a synchronized region on an object before calling Wait or Pulse on that object. Wait releases the lock if it is held and waits to be notified. When Wait is notified, it returns and has obtained the lock again. Notify signals for next thread in wait queue to proceed.

Monitor.Enter(b)
Monitor.Wait(b, 1000)
. . . ' do some work
Monitor.Exit(b)

How to run?

This is a console application, which demonstrates the Multithreading capability of .NET in Visual Basic.

This is a banking application which demonstrate the use of synchronization, to see why synchronization is necessary comment the Monitor.Enter(Me) and Monitor.Exit(Me), the result will vary and u will get the feel why synchronization is needed.



Example of Multithreading

Creating Threads

To create threads lets work with an example. The following example is an extract from Steven Holzner's reference, Programming with Visual Basic.NET- Black Book. Open a new windows application and name it as Thread and add a class named count1 using the Projects->Add Class item. This class will count from 1 to a specified value in a data member named CountTo when you call the Count method. After the count has reached the value in CountTo, a FinishedCounting event will occur. The code for the Count class looks like this:

Public Class Count1
Public CountTo as Integer
Public event FinishedCounting(By Val NumberOfMatches as Integer)
Sub Count()
Dim ind,tot as Integer
tot=0
For ind=1 to CountTo
tot+=1
Next ind
RaiseEvent FinishedCounting(tot)
'makes the FinishedCounting event to occur
End Sub
End Class


Let's use this class with a new thread. Get back to the main form and create an object of this class, counter1, and a new thread, Thread1. The code looks like this:

Public Class Form1 Inherits System.Windows.Forms.Form
Dim counter1 as new Count1()
Dim Thread1 as New System.Threading.Thread(Address of counter.Count)


Drag a Button and two TextBoxes (TextBox1, TextBox2) onto the form. Enter a number in TextBox1. The reason for entering a number in textbox is to allow the code to read the value specified in TextBox1 and display that value in TextBox2, with threading. The code for that looks like this:

Public Class Form1 Inherits System.Windows.Forms.Form
Dim counter1 as new Count1()
Dim Thread1 as New System.Threading.Thread(Address of counter.Count)
Private Sub Button1_Click(ByVal sender as System.Object, ByVal e as System.EventArgs)_
Handles Button1.Click
TextBox2.Text=" "
counter1.CountTo=TextBox1.Text
AddHandler counter1.FinishedCounting,AddressOfFinishedCountingEventHandler
'adding handler to handle FinishedCounting Event
Thread1.Start()
'starting the thread
End Sub
Sub FinishedCountingEventHandler(ByVal Count as Integer)
'FinishedCountingEventHandler
TextBox2.Text=Count
End Sub


The result of the above code displays the value entered in TextBox1, in TextBox2 with the difference being the Thread counting the value from 1 to the value entered in TextBox1.

No comments: