There are times where you first have to compare different ways of achieving the same goal. Using threads or backgroundworkers basically do the same thing, but, only if you use them right. Today, I will show compare unsafe threading calls to backgroundworker calls.
Threads
If you have never heard the term “Threads” before, let me explain. Any application makes use of threads to either show you information or a screen or to allow for long running tasks to complete. Now, threads are tricky and data is tricky. Sometimes, you will encounter a situation that may possibly freeze your application due to a long running task. So, instead of slamming all the code into one form, you have several threads. Each thread can run independently without affecting any other threads or user process.
Here is more information regarding threads.
BackgroundWorker
A BackgroundWorker object allows you to run an operation on a separate, dedicated thread. Similar to threads, time-consuming operations like downloads and database transactions that can cause your user interface to hang can be properly managed by running in a separate thread.
Here is more information on the BackgroundWorker class.
Let’s Do a Project
The aim of this project is to show you how to use threads to make unsafe calls, safe calls, and use a backgroundworker to make safe calls.
Create a new Visual Basic Windows Forms project and add another form to your project. Both forms should look like Figures 1 and 2:
Figure 1: Form 1
Figure 2: Form 2
Code
All of the code will take place on Form 1. Add the following namespaces:
Imports System Imports System.ComponentModel Imports System.Threading Imports System.Windows.Forms
These namespaces allow us to work with threads.
Add the following variable objects to your code:
Delegate Sub SetTextCallback(ByVal [text] As String) Private demoThread As Thread = Nothing Private WithEvents backgroundWorker1 As BackgroundWorker Private textBox1 As TextBox Private WithEvents setTextUnsafeBtn As Button Private WithEvents setTextSafeBtn As Button Private WithEvents setTextBackgroundWorkerBtn As Button
Here, I created a delegate procedure named SetTextCallBack, which we will later use with a thread operation. I created a thread object named demoThread as well as a Backgroundworker object. The following objects are simply controls that you will access through code.
For more information on Delegates, read here.
Using Threads
Add the following code:
Private Sub setTextUnsafeBtn_Click( _ ByVal sender As Object, _ ByVal e As EventArgs) Handles setTextUnsafeBtn.Click Me.demoThread = New Thread( _ New ThreadStart(AddressOf Me.ThreadProcUnsafe)) Me.demoThread.Start() End Sub Private Sub ThreadProcUnsafe() Me.textBox1.Text = "This text was set unsafely." End Sub
This is an unsafe way to use threads to do tasks. Why? Before I get into details, add the following safe way to use a thread.
Private Sub setTextSafeBtn_Click( _ ByVal sender As Object, _ ByVal e As EventArgs) Handles setTextSafeBtn.Click Me.demoThread = New Thread( _ New ThreadStart(AddressOf Me.ThreadProcSafe)) Me.demoThread.Start() End Sub Private Sub ThreadProcSafe() Me.SetText("This text was set safely.") End Sub
If you look closely, you may be able to see the subtle, yet big, difference between the preceding two code segments.
Backgroundworker
Add the following code for the Backgroundworker:
Private Sub SetText(ByVal [text] As String If Me.textBox1.InvokeRequired Then Dim d As New SetTextCallback(AddressOf SetText) Me.Invoke(d, New Object() {[text]}) Else Me.textBox1.Text = [text] End If End Sub Private Sub setTextBackgroundWorkerBtn_Click( _ ByVal sender As Object, _ ByVal e As EventArgs) Handles setTextBackgroundWorkerBtn.Click Me.backgroundWorker1.RunWorkerAsync() End Sub Private Sub backgroundWorker1_RunWorkerCompleted( _ ByVal sender As Object, _ ByVal e As RunWorkerCompletedEventArgs) _ Handles backgroundWorker1.RunWorkerCompleted Me.textBox1.Text = _ "This text was set safely by BackgroundWorker." End Sub
Here, I have made use of the BackgroundWorker to set the text property of a textbox. Because the BackgroundWorker inherently spawns a separate thread, all the work will not get done on one thread only.
Conclusion
Using threads properly or using BackgroundWorker objects can speed up your application’s performance and reduce freezing of applications. Although the above coding samples were used on simple operations, the long term effects in your application’s speed will be tangible.