Threads Made Easy in Visual Basic

Introduction

Multithreading can be challenging. Using a lot of threads can make an application much more difficult to debug and buggier. The Parallel FX Library was created to make your life a little easier. Now the features that were in a separate download are part of the .NET Framework 4.0, and they can add a little zip to your application with a lot fewer headaches.

Everyone wants substantial performance increases and when needed programmers often turn to multithreading. However, if you follow the basic mathematics of Amdahl's law and Gustafson's law then you know that just chunking the work by adding threads does not produce linear increases in performance. Use threads sparingly but use them more safely with the features presented in this article.

Preparing Your Microsoft Visual Studio 2010 Environment

To try the samples create a new Console application in Microsoft Visual Studio 2010. To use the Parallel features make sure your project is using the .NET Framework 4.0. To select the target framework click the Project|project_name Properties menu item, switch to the Compile tab and click the Advanced Compile Options. At the bottom of that dialog is the Target framework select-see Figure 1. Change the target framework to the .NET Framework 4 Client Profile.


Figure 1 - Make sure the target framework is .NET 4.0

The Parallel extensions used for the demo are in System.Threading.Tasks, so add a reference to this namespace in your project using an Imports statement.

Using Parallel.ForEach

Parallel.ForEach has several overloaded versions that accept an IEnumerable(Of T) collection and an Action generic delegate. The method executes a for each operation and iterations may be run in parallel. The following fragment uses the Shared Enumerable.Range method and generates a range of numbers from 1 to 1000. The LINQ query selects just the even numbers and the Paralle.ForEach method uses a Lambda expression to write the contents to the console in parallel. Figure 2 shows all of thread spun up for this statement.

  Dim data = Enumerable.Range(1, 1000)

' Implicit line continuation - No line continuation. Yeah!
Dim evens = From e In data
     Where e Mod 2 = 0
     Select e

Parallel.ForEach(evens, Sub(i) Console.Write(i.ToString() + ", "))
Console.ReadLine()


Figure 2: Threads galore for Parallel.ForEach

It is worth noting that the order of the data is not necessarily preserved, which is a consideration if you are using Parallel.ForEach.

Threads Made Easy in Visual Basic

Using the AsParallel Extension Method for IEnumerable(OF T)

The next example uses IEnumerable(Of T).AsParallel to execute the LINQ query in parallel. Again in this instance the order of the items will not be preserved.

  Dim data = Enumerable.Range(1, 1000)


' similar results to sending to console in parallel
Dim evens2 = From e In data.AsParallel
    Where e Mod 2 = 0
    Select e

Array.ForEach(Of Integer)(evens2.ToArray(), Sub(i) Console.WriteLine(i))
Console.ReadLine()

You can click on Debug|Windows|Threads to see the threads created or Debug|Windows|Parallel Tasks to view the status of the parallel tasks-see Figure 3.

[Tip: A nice feature of Microsoft Visual Studio 2010 is when you float and then dock a frame in VS2010 the docked window returns automatically to its default dock position; this is a lot nicer than trying to drag it back to its docked position.]

[tasks3.jpg]
Figure 3: View the status of parallel tasks by selecting Debug|Windows|Parallel Tasks while debugging in Visual Studio 2010

Maintaining Order with AsParallel

If you want to maintain the order of items in a parallel LINQ query then call IEnumerable(Of T).AsParallel.AsOrdered on the data source. To quote the help documentation "A natural tension exists between performance and preserving order in parallel processing". This tension is probably manifested as slightly poorer performance in the parallel processing, but if you need to preserve the original order then use AsOrdered as demonstrated in the follow code fragment.

  Dim data = Enumerable.Range(1, 1000)


' Parallel while maintaining order
Dim evensOrdered = From e In data.AsParallel.AsOrdered
       Where e Mod 2 = 0
       Select e

Array.ForEach(Of Integer)(evensOrdered.ToArray(), Sub(i) Console.WriteLine(i))
Console.ReadLine()

On a side note, notice that .NET 4.0 supports Lambda expressions that are subroutines. That is, you can use Sub or Function to write your Lambda expressions. Function only expressions where limiting in earlier versions of .NET. Function-only expressions meant you had to contrive a return value whether you needed on or not. (Good job Microsoft.)

Calling Parallel.Invoke

Parallel.Invoke accepts a ParamArray-an arbitrary number-of Action delegates and performs these tasks in Parallel. The following fragment demonstrates how to write several strings to the console in parallel. (Of course, you can actually invoke methods that perform real work, but you get the idea.)

   Dim master() As String = New String() {
  "Master! Master! I have these two dogs the past that limits ",
   "me and the future that inspires me fighting inside of me. Which one will win? ",
    "Master replies: the one you feed the most."}

 Parallel.Invoke(Sub() Console.WriteLine(master(0)), Sub() Console.WriteLine(master(1)),
                        Sub() Console.WriteLine(master(2)))
 Console.ReadLine()

Of course, you can still use background workers, monitors, locks, or the ThreadPool if you like, but for simplicity see if you can't get the job done using the new, managed parallel features of .NET 4.0.

Conclusion

The only constant is change. Upgrade to Microsoft Visual Studio 2010. Just getting rid of line continuation is enough for me, but upgrade so you can use LINQ, Parallel constructs, the new and improved Entity Framework features and all of the cool features in VS2010. And thank you for reading all of these years.



About the Author

Paul Kimmel

Paul Kimmel is the VB Today columnist for CodeGuru and has written several books on object-oriented programming and .NET. Check out his upcoming book Professional DevExpress ASP.NET Controls (from Wiley) now available on Amazon.com and fine bookstores everywhere. Look for his upcoming book Teach Yourself the ADO.NET Entity Framework in 24 Hours (from Sams). You may contact him for technology questions at pkimmel@softconcepts .com. Paul Kimmel is a Technical Evangelist for Developer Express, Inc, and you can ask him about Developer Express at paulk@devexpress.com and read his DX blog at http:// community.devexpress.com/blogs/paulk.

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: April 22, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Database professionals — whether developers or DBAs — can often save valuable time by learning to get the most from their new or existing productivity tools. Whether you're responsible for managing database projects, performing database health checks and reporting, analyzing code, or measuring software engineering metrics, it's likely you're not taking advantage of some of the lesser-known features of Toad from Dell. Attend this live …

  • Live Event Date: May 6, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT While you likely have very good reasons for remaining on WinXP after end of support -- an estimated 20-30% of worldwide devices still are -- the bottom line is your security risk is now significant. In the absence of security patches, attackers will certainly turn their attention to this new opportunity. Join Lumension Vice President Paul Zimski in this one-hour webcast to discuss risk and, more importantly, 5 pragmatic risk mitigation techniques …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds