ARTICLE

Understanding Threading in .NET Framework using VB.NET

Posted by Chandrakant Parmar Articles | Visual Basic 2010 April 21, 2005
This article describes how to use threading model in .NET Framework including creating, joining, suspending, killing, and interlocking threads.
 
Reader Level:

Summary

Thread basics using followings:

  • How to Create thread; use System.Thread() class and create an instance.

  • How to Join thread; use object.Join() to join threads.

  • How to Suspend thread; use object.Sleep(<No of seconds>) to Suspend thread.

  • How to Kill thread; use object.Abort() to Suspend thread.

  • Using Interlocked class which uses Increment and decrement method to increment and decrement values.
Thread Synchronization using followings:
  • Using Locks: allows to mark a lock on the critical section of the code(program), provides synchronization to an object and then to execute the lock is in effect.

  • Using Monitor: allows to decide when to enter and exit the synchronization, and it lets us wait for another area of code to become free. Monitor acts as a smart lock on a resource. When the we need synchronization, we can call the enter() method of the monitor passing the object we want to monitor. We can explicitly choose to wait () method of the monitor to control thread ordering. In case of using wait () waiting threads will be allowed to notified of a chance to run again if the active thread calls Pulse (). This signals the CLR that there has been a chance in the state that might free a thread that is waiting. The CLR tracks of the fact that the earlier thread asked to wait, and the thread will be guaranteed access in the order in which the wait where requested. Exit () can be called once when the thread is finished with the monitor.
Overview

Architecture of CLR

Threading support is in built under Common Language Runtime provided by Microsoft .NET Framework.

Understanding Threading

  1. Threads are basically light weight processes responsible for multitasking within a single application.

  2. The base class used for threading is System.Threading.

  3. Threads are managed under the Common Language Runtime, programmers don't have to manage any threads explicitly.

  4. Using threading with the combination of components it is recommended to use explicit definition and management of the thread.

  5. Threads are implement when you have situations in which you want to perform more then one task at a time.

  6. In case of Synchronization. Since you have limited amount of recourses, you may have to restrict the access to the resource to one thread at a time. In this situations you may implement locking on the threading to over come the scenarios.

  7. An apartment is a logical container within a process and is used for objects that shares the same thread-access requirement. Object in the apartment can all receive method call from any object in any thread in the apartment. And managed object (object created within CLR) are responsible for thread safety.

  8. Threads can be used under the situation where we must wait for an event such as user input, a read from file, or receipt of data over the network. Freeing the memory to turn it a safe, and it makes our program to appear to run more quickly.

Working with Thread

Create new instance of Thread object. Thread constructor accepts one parameters that is delegate.

MS CLR provides ThreadStart delegate class for starting the thread.

Example:

Dim myThread As New Thread(AddressOf myFunc)

To run this thread we need following

Dim t1 As New Thread(AddressOf Incrementer)

To instantiate this we need followings

t1.Start()

Detailed example is as below

Imports System
Imports System.Threading
Namespace Programming_CSharp
Class Tester
Shared Sub Main()
' make an instance of this class
Dim t As New Tester
' run outside static Main
t.DoTest()
End Sub
'Main
Public Sub DoTest()
' create a thread for the Incrementer
' pass in a ThreadStart delegate
' with the address of Incrementer
Dim t1 As New Thread(AddressOf Incrementer)
' create a thread for the Decrementer
' pass in a ThreadStart delegate
' with the address of Decrementer
Dim t2 As New Thread(AddressOf Decrementer)
' start the threads
t1.Start()
t2.Start()
End Sub
'DoTest
' demo function, counts up to 1K
Public Sub Incrementer()
Dim i As
Integer
For i = 0 To 999
Console.WriteLine("Incrementer: {0}", i)
Next i
End Sub
'Incrementer
' demo function, counts down from 1k
Public Sub Decrementer()
Dim i As
Integer
For i = 1000 To 0 Step -1
Console.WriteLine("Decrementer: {0}", i)
Next i
End Sub
'Decrementer
End Class
'Tester
End Namespace 'Programming_CSharp

Output:

Incrementer: 102
Incrementer: 103
Incrementer: 104
Incrementer: 105
Incrementer: 106
Decrementer: 1000
Decrementer: 999
Decrementer: 998
Decrementer: 997

Joining Threads

Once thread starts running and in a situation when we need to tell thread to stop processing and wait until a second thread to complete the processing we need to join the 1st thread to the 2nd thread. Use following for the same. This will join the second thread to the 1st.

Example:

t2.Join( )

Suspending Thread

In a situation we some time needs to suspend running thread.

Example:

t2.Sleep(<No of Seconds>)

Killing Thread

Threads has to die after the execution of the process in normal situations, occasionally it is required for the programmer to kill a thread. Threads can be killed using the following.

Example:

t2.Abort()

Advanced Threading

Synchronization

Recollect the discussion we had before in some situations we need to synchronize the running threads, so we can modify the running thread and its resources.

Imports System
Imports System.Threading
Namespace Programming_CSharp
Class Tester1
Private counter As Integer = 0
Shared Sub Main()
' make an instance of this class
Dim t As New Tester
' run outside static Main
t.DoTest()
End Sub
'Main
Public Sub DoTest()
Dim t1 As New Thread(AddressOf Incrementer)
t1.IsBackground =
True
t1.Name = "ThreadOne"
t1.Start()
Console.WriteLine("Started thread {0}", t1.Name)
Dim t2 As New Thread(AddressOf Incrementer)
t2.IsBackground =
True
t2.Name = "ThreadTwo"
t2.Start()
Console.WriteLine("Started thread {0}", t2.Name)
t1.Join()
t2.Join()
' after all threads end, print a message
Console.WriteLine("All my threads are done.")
End Sub
'DoTest
' demo function, counts up to 1K
Public Sub Incrementer()
Try
While counter < 1000
Dim temp As Integer = counter
temp += 1
' increment
' simulate some work in this method
Thread.Sleep(1)
' assign the decremented value
' and display the results
counter = temp
Console.WriteLine("Thread {0}. Incrementer: {1}", Thread.CurrentThread.Name, counter)
End
While
Catch
Finally
Console.WriteLine("Thread {0} Exiting. ", Thread.CurrentThread.Name)
End
Try
End Sub
'Incrementer
End Class
'Tester
End Namespace 'Programming_CSharp

Output:

Started thread ThreadOne
Started thread ThreadTwo
Thread ThreadOne. Incrementer: 1
Thread ThreadOne. Incrementer: 2
Thread ThreadOne. Incrementer: 3
Thread ThreadTwo. Incrementer: 3
Thread ThreadTwo. Incrementer: 4
Thread ThreadOne. Incrementer: 4
Thread ThreadTwo. Incrementer: 5
Thread ThreadOne. Incrementer: 5
Thread ThreadTwo. Incrementer: 6
Thread ThreadOne. Incrementer: 6

Using Interlock

MS CLR provides synchronization tools and mechanisms. This will allow programmers to place locking over running threads.

VB provides a special class called interlocked just for the reason of locking. This consists of two methods Increment and Decrement.

Example:

Public Sub Incrementer()
Try
Dim counter As
Integer
Do While
counter < 1000
Interlocked.Increment(counter)
' simulate some work in this method
Thread.Sleep(1)
' assign the decremented value
' and display the results
Console.WriteLine("Thread {0}. Incrementer: {1}", Thread.CurrentThread.Name, counter)
Loop
Catch
End
Try
End
Sub

Output (excerpts):

Started thread ThreadOne
Started thread ThreadTwo
Thread ThreadOne. Incrementer: 1
Thread ThreadTwo. Incrementer: 2
Thread ThreadOne. Incrementer: 3
Thread ThreadTwo. Incrementer: 4
Thread ThreadOne. Incrementer: 5
Thread ThreadTwo. Incrementer: 6
Thread ThreadOne. Incrementer: 7
Thread ThreadTwo. Incrementer: 8
Thread ThreadOne. Incrementer: 9
Thread ThreadTwo. Incrementer: 10
Thread ThreadOne. Incrementer: 11
Thread ThreadTwo. Incrementer: 12
Thread ThreadOne. Incrementer: 13
Thread ThreadTwo. Incrementer: 14
Thread ThreadOne. Incrementer: 15
Thread ThreadTwo. Incrementer: 16
Thread ThreadOne. Incrementer: 17
Thread ThreadTwo. Incrementer: 18
Thread ThreadOne. Incrementer: 19
Thread ThreadTwo. Incrementer: 20

Using Locks

A lock marks a critical section of the code, provides synchronization to an object.

Public Sub Incrementer()
Try
Dim counter As
Integer
Do While counter < 1000
SyncLock
Me
Dim temp As Integer = counter
temp += 1
Thread.Sleep(1)
counter = temp
End
SyncLock
' assign the decremented value
' and display the results
Console.WriteLine("Thread {0}. Incrementer: {1}", Thread.CurrentThread.Name, counter)
Loop
Catch
End
Try
End
Sub

Using Monitor

There are situations where the programmer need to monitor the running threads for which we can use the followings.

Monitor.Enter(Me)

Race Condition and Deadlocks

There are situations when the Process goes for deadlock situation. Synchronization is little tricky to handle.

Race Conditions

This situation occurs when success of one program is depends on uncontrolled order of execution of certain processes(Two Independent Threads).

We can over come this situation by sing Join() and using Monitor() Wait() etc...

Deadlocks

In the situations when one thread is dependent on the other thread to complete it is some time possible that unknowingly one thread can wait for the other to finish, so the second thread can go ahead and run the 2nd process. In few occasions each thread may go in a loop to wait for the next thread to complete the processing to start. where both the threads are waiting for each other to complete and none of them are actually doing any processing.

NOTE: THIS ARTICLE IS CONVERTED FROM C# TO VB.NET USING A CONVERSION TOOL. ORIGINAL ARTICLE CAN BE FOUND ON C# CORNER (WWW.C-SHARPCORNER.COM).

share this article :
post comment
 

can u please help me how to kill a process and threads with name "myapplication" when clicking same application in
second time
in my application i have one thread assigned to a method
i tried with process.kill method
but is not killing all the threads of that application


thanks in advance please send me a mail
bhupal48@gmail.com

Posted by bhupal b Aug 19, 2010

Hi, I do use object.Abort() to suspend thread, but what happen is that the thread is indeed suspended, but the process (method) that was running in that thread, moves to the main thread and the application is blocked until the process (method) finishes.

Posted by Rudy Welvaert Sep 21, 2007
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor
PREMIUM SPONSORS
  • The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
    The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor