Thread Synchronization

[This documentation is for preview only, and is subject to change in later releases. Blank topics are included as placeholders.]

As you write a threaded application, you may need to synchronize individual threads with other parts of your program. Synchronization provides a compromise between the unstructured nature of multithreaded programming and the structured order of synchronous processing.

You use synchronization techniques:

  • To explicitly control the order in which code runs whenever tasks must be performed in a specific sequence

    -or-

  • To prevent the problems that can occur when two threads share the same resource at the same time.

For example, you could use synchronization to cause a display procedure to wait until a data retrieval procedure that is running on another thread is complete.

Synchronization Techniques

There are two approaches to synchronization, polling and using synchronization objects. See Advanced Synchronization Techniques for more information on synchronization objects.

Polling

Polling repeatedly checks the status of an asynchronous call from within a loop. Polling is the least efficient way to manage threads because it wastes resources by repeatedly checking the status of the various thread properties.

For example, the IsAlive property can be used when polling to see if a thread has exited. Use this property with caution because a thread that is alive is not necessarily running.

You can use the thread's ThreadState property to get more detailed information about a thread's status. Because threads can be in more than one state at any given time, the value stored in ThreadState can be a combination of the values in the System.Threading.ThreadState enumeration. Consequently, you should carefully check all relevant thread states when polling. For example, if a thread's state indicates that it is not Running, it may be done. On the other hand, it may be suspended or sleeping.

Waiting for a Thread to Finish

The Thread.Join method is useful for determining if a thread has completed before starting another task. The Join method waits a specified amount of time for a thread to end. If the thread ends before the timeout, Join returns True; otherwise it returns False.

As you can imagine, polling sacrifices many of the advantages of multithreading in return for control over the order that threads run. Because it is so inefficient, polling is generally not recommended. A more efficient approach would use the Join method to control threads. Join causes a calling procedure to wait either until a thread is done or until the call times out if a time-out is specified. The name "join" is based on the idea that creating a new thread is a fork in the execution path. You use Join to merge separate execution paths into a single thread again.

Set and Join Threads

Figure 1 Threading

One point should be clear: Join is a synchronous or blocking call. Once you call Join, or a wait method of a wait handle, the calling procedure stops and waits for the thread to signal that it is done.

Sub JoinThreads()
    Dim Thread1 As New System.Threading.Thread(AddressOf SomeTask)
    Thread1.Start()
    Thread1.Join()      ' Wait for the thread to finish.
    MsgBox("Thread is done")
End Sub
Sub SomeTask()
    ' Insert code to perform a task here.
End Sub

These simple ways of controlling threads, which are useful when you are managing a small number of threads, are difficult to use with large projects. Advanced Synchronization Techniques discusses some techniques you can use to synchronize threads.

See Also

Concepts

Advanced Multithreading with Visual Basic

Parameters and Return Values for Multithreaded Procedures

Other Resources

Multithreading in Visual Basic