Heavyweight Threading


Visual Basic .NET Unleashed
By Paul Kimmel
Table of Contents
Chapter 14.  Multithreaded Applications

Heavyweight Threading

Thus far all the examples could have been accomplished by creating an instance or instances of the Thread class and managing the thread directly. It is easiest to implement asynchronous behavior using the Timer control and the Application.Idle event, and easier to use threads in the thread pool. Using Thread objects is not significantly more difficult, but you do have to actively manage the threaded behavior and the thread objects. When you're writing code for money, the more difficult something is, the more it will cost. Unfortunately, that extra cost is seldom linear.

Creating and Using Threads

The basic steps for using the Thread class are an expansion of using the thread pool. The mechanics of using the Thread class include creating an instance of the Thread class, passing a worker method in the form of a delegate to the Thread constructor, setting Thread.IsBackground = True, and cleaning up when the thread is finished. In between you will have to contrive ways to synchronize the thread's interaction with shared resources; you can use several of the ways already discussed, including the SyncLock..End SyncLock construct, WaitHandle objects, and the Monitor class.

Table 14.1 lists some of the basic members of the Thread class that are available to facilitate thread management.

Table 14.1. Members of the Thread Class
Member Name Description
Instance Property
ApartmentState Gets or sets the thread apartment model, either single-threaded apartment (STA) or multithreaded apartment (MTA).
CurrentThread Returns the currently running thread.
IsAlive Returns True unless the thread state is Unstarted, Stopped, or Aborted.
IsBackground True if the thread is a background thread; does not prevent a process from terminating.
Priority Sets or gets the ThreadPriority, which is Normal, Lowest, Highest, BelowNormal, or AboveNormal.
ThreadState Returns one value from the ThreadState enumeration.
Instance Methods
Abort Usually terminates the thread after raising a ThreadAbortException.
Interrupt Interrupts a thread in the WaitSleepJoin state.
Join Blocks the calling thread until it terminates.
Resume Resumes a thread that has been suspended .
Start Starts the thread.
Suspend Suspends the thread (has no effect on a suspended thread).
Shared Methods
GetDomain Returns the AppDomain that the current thread is running on; for example, an AppDomain can be used to get the thread ID.
Sleep Blocks the current thread for a specified number of milliseconds .
SpinWait Causes a thread to wait a specified number of iterations.

Thread Demo

You already have some experience with the Dice demo. An updated copy of the Dice demo is in ThreadRollDice2 for you to compare to the first version that uses ThreadPool. A much shorter demonstration can be completed using the Monitor example from the section "Synchronization with the Monitor Class" and still demonstrate the salient differences between threading with ThreadPool and with the Thread class.

The revised complete application is defined on this book's Web site in the MonitorDemo2 folder. Listing 14.6 only contains the revised shared Sub Main from Listing 14.5 because that is pretty much all we have to change to use Thread objects.

Listing 14.6 Using instances of the Thread class
  1:  Public Shared Sub Main()  2:   3:  Dim Demo As New MonitorDemo()  4:  Demo.FillArray()  5:  Dim SortThread As New Thread(AddressOf Demo.SortArray)  6:  SortThread.IsBackground = True  7:   8:  Dim PrintThread As New Thread(AddressOf Demo.PrintArray)  9:  PrintThread.IsBackground = True  10:   11:  SortThread.Start()  12:  PrintThread.Start()  13:   14:  SortThread.Join()  15:  PrintThread.Join()  16:   17:  Console.ReadLine()  18:   19:  End Sub 

As you recall from the earlier listing, the complete sample is a console application that uses the Monitor class to swap between two threads that sort and print an array. After each complete set of inner loop comparisons, the sorted i th element is printed on the second thread. In the original listing, ThreadPool was used. Here we use Thread objects that we create.

Lines 56 and 89 each create a Thread object and set its IsBackground property to True. If you forget to set IsBackground to True and forget to stop the thread, your application will mysteriously seem to hang after you exit, while any running foreground threads unwind. Notice that just as with ThreadPool, we are assigning work to the thread in the form of a delegate. The delegate used to construct a Thread object is a ThreadStart delegate, which is essentially the address of a subroutine that takes no arguments. (Recall that the ThreadPool.QueueUserWorkItem method takes a WaitCallBack delegate that requires a single Object argument.)

The two threads are started on lines 11 and 12, and each thread is blocked in turn until each exits. The Console.ReadLine call is provided to suspend closing the console until you have had a chance to review the results.


Visual BasicR. NET Unleashed
Visual BasicR. NET Unleashed
Year: 2001
Pages: 222

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net