Browse DevX
Sign up for e-mail newsletters from DevX


How To Pass Parameters to Threads in Windows Forms Applications—and Get Results

Launching new threads is easy, but it's not as obvious how you can pass parameters to the threads and get the results back. In addition, accessing Windows Forms controls from multiple threads can cause problems. In this article, you'll see how to pass parameters, receive results, and access controls safely from multiple threads in a Windows Forms application.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

he .NET framework makes it easy to start code execution on a new thread—improving user interface design by letting you execute lengthy procedures on one thread while leaving the UI thread active and available to handle user interaction.

Starting a new thread is simple in VB.NET—you add the System.Threading namespace to your module to simplify naming, create a new thread using a delegate to tell it which method to start in, and then call its Start method to begin execution.

For example, suppose you have a button on a form; when the user presses the button, you want to launch a separate thread that performs some task. For this article, a simple counter method suffices to simulate a long-running procedure.

Note: The downloadable code for this article contains both VB.NET and C# versions.

Sub Count() Dim i As Integer ' loop 25 times For i = 1 To 25 ' show the counter value Console.WriteLine(i.ToString) ' sleep 100 milliseconds Thread.CurrentThread.Sleep(100) Next End Sub

But rather than showing the user an hourglass cursor and disabling the button while the task executes, you want to let the user continue to interact with the program. Create a new Windows Form with a button named btnLaunchThread and set its Text property to Launch Thread. Next, create a Count() method that counts from 1 to 25, writing the current counter value to the Output window. Because that would normally happen very quickly, the code also uses the Thread.CurrentThread method to get the currently executing thread, and causes it to sleep for 100 milliseconds, which simulates a lengthy process better. Here's the code.

' At the top of the form Imports System.Threading ' Inside the class Private Sub btnLaunchThread_Click( _ ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLaunchThread.Click ' create the thread using a Count delegate Dim t As Thread = New Thread(AddressOf Count) ' start the thread t.Start() End Sub

Run the code and click the Launch Thread button. You'll see the output window slowly fill with numbers from 1 to 25. Click the button again—in fact, click it several times. What happens? Each time you click the button, the application launches a new thread, which then starts displaying numbers in the output window. To make things a little clearer, you can assign each thread a name and display that as well. The sample Form1.vb file contains the altered code:

Option Strict On Imports System.Threading Public Class Form1 Inherits System.Windows.Forms.Form Dim threadCount As Integer ' omitted -- Windows Form Designer generated code " Private Sub btnLaunchThread_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnLaunchThread.Click Dim t As Thread = New Thread(AddressOf Count) threadCount += 1 t.Name = "Thread " & threadCount.ToString t.Start() End Sub Sub Count() Dim i As Integer For i = 1 To 25 Console.WriteLine(Thread.CurrentThread.Name & _ ": " & i.ToString) Thread.CurrentThread.Sleep(100) Next End Sub End Class

After changing the code, when you click the button several times, you'll see each thread's name appear in front of the counter value. That's straightforward enough. Each button click launches an individual thread that counts from 1 to 25. But what if you didn't know how many times to loop? What if you wanted the user to specify a value for the number of counter iterations, and pass that to the new thread?

Here's where the simplicity breaks down a little. The Thread class constructor accepts only a ThreadStart delegate (the delegate that represents the method in which to start the thread), and there's no overloaded Thread.Start() method that accepts parameter values.

Thanks for your registration, follow us on our social networks to keep up-to-date