Walkthrough: Multithreading
This walkthrough demonstrates how to create a multithreaded application that searches a text file for occurrences of a word. The walkthrough consists of four main parts:
- Defining a class with a method that can be run on a thread independently
- Handling events raised by other threads
- Starting a new thread to run a method
- Implementing a
Cancelbutton that stops the thread
To build the code example for this topic
- Open a new Visual Basic .NET Windows Application project, and create a form named
Form1. - Add two buttons and four text boxes to
Form1. - Name the objects as shown in the following table.
Object Property Setting First button Name, Text Start, Start Second button Name, Text Cancel, Cancel First text box Name, Text SourceFile, "" Second text box Name, Text CompareString, "" Third text box Name, Text WordsCounted, "0" Fourth text box Name, Text LinesCounted, "0" - Add a label next to each text box. Set the Text property for each label as shown in the following table.
Object Property Setting First label Text Source File Second label Text Compare String Third label Text Matching Words Fourth label Text Lines Counted
To define the method that will run on a separate thread
- From the Project menu, choose Add Class to add a class to the project. The Add New Item dialog is displayed.
- Select Class from the templates window and type
Words.vbin the name field. - Click Open. The
Wordsclass is displayed. - Add an Option Compare statement to the top of the
Wordsclass module, above the Class statement:Option Compare Text ' Case insensitive search. ' Use Option Compare Binary for case sensitive search.
- Add the following code to the
Wordsclass:Public Class Words Private strloc As Integer Private RemainingString As String Private SourceString As String Public SourceFile As String Public CompareString As String Public WordCount As Integer Private LinesCounted As Integer = 0 Public Event Status(ByVal LinesCounted As Integer, _ ByVal WordsMatched As Integer) Public Event FinishedCounting(ByVal NumberOfMatches As Integer) Sub CountWords() Dim f As System.IO.File Dim mystream As System.IO.StreamReader Dim mystr As String = " " ' Initialize to not empty. If SourceFile = System.String.Empty _ Or CompareString = System.String.Empty Then MsgBox("You must set the SourceFile " & _ " and CompareString fields before calling CountWords.") Exit Sub End If If f.Exists(SourceFile) = False Then MsgBox("Error; Unable to open the input file.") Exit Sub End If Try mystream = f.OpenText(SourceFile) ' Open a new stream. ' Do until the stream returns Nothing at end of file. Do Until IsNothing(mystr) mystr = mystream.ReadLine WordCount += CountInString(1, mystr, CompareString) LinesCounted += 1 ' Increment line count. ' Raise an event so the form can monitor progress. RaiseEvent Status(LinesCounted, WordCount) Loop Catch eof As IO.EndOfStreamException ' No action is necessary, the end of the stream has been reached. Catch IOExcep As IO.IOException ' Some kind of error occurred. MsgBox(IOExcep.Message) Finally mystream.Close() ' Close the file. End Try RaiseEvent FinishedCounting(WordCount) End Sub Private Function CountInString(ByVal StartingPoint As Integer, _ ByVal SourceString As String, _ ByVal CompareString As String) As Integer ' This function counts the number of times ' a word is found in a sentence. ' If the word is found, the function is called recursively on ' the remainder of the string. strloc = Strings.InStr(StartingPoint, SourceString, CompareString) If strloc <> 0 Then CountInString += 1 CountInString += CountInString(strloc + Strings.Len(CompareString), _ SourceString, CompareString) End If End Function End Class
To handle events from the thread
- Add the following event handlers to your main form:
Sub FinishedCountingEventHandler(ByVal WordCount As Integer) ' This event handler is called when the word-counting thread ' raises a FinishedCounting event indicating that ' the whole file has been checked. The WordCount parameter ' is the number of matches found. Me.WordsCounted.Text = CStr(WordCount) MsgBox("Finished counting words.") End Sub Sub LineCountEventHandler(ByVal LinesCounted As Integer, _ ByVal WordsMatched As Integer) ' This event handler is called when the word-counting thread ' raises a status event after reading each line ' from the source file. Me.LinesCounted.Text = CStr(LinesCounted) Me.WordsCounted.Text = CStr(WordsMatched) End Sub
To start and call a new thread that runs the WordCount method
- Add the following code to the Declarations section of
Form1:Dim Thread As System.Threading.Thread
- Add the following procedure to your program:
Sub StartThread() Dim WC As New words() Me.WordsCounted.Text = "0" ' Set the values of some object fields, because ' you cannot create a thread and pass it a method ' signature that contains parameters. WC.CompareString = Me.CompareString.Text ' The string to look for. WC.SourceFile = Me.SourceFile.Text ' The file to search. ' Associate an event handler with the event that ' is raised when the new thread is done. AddHandler WC.FinishedCounting, AddressOf _ FinishedCountingEventHandler ' Associate an event handler with the event that ' is raised after each line is read. AddHandler WC.Status, AddressOf LineCountEventHandler ' Create the new thread. Thread = New System.Threading.Thread(AddressOf WC.CountWords) ' Start the new thread. Thread.Start() End Sub - Call the
StartThreadmethod from theStartbutton on your form:Private Sub Start_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Start.Click StartThread() End Sub
To implement a Cancel button that stops the thread
- Add the following procedure to your main form:
Protected Sub StopThread(Thread as System.Threading.Thread) ' Call StopThread from a Cancel button procedure. Thread.Abort() End Sub - Call the
StopThreadprocedure from theclickevent handler for theCancelbutton.Private Sub Cancel_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles Cancel.Click StopThread(Thread) End Sub
Testing
You can now test the application to make sure it works correctly.
To test the application
- Press F5 to run the application.
- When the form is displayed, enter the file path in the
sourceFiletextbox for a file you want to test. For example, assuming your test file is named Test.txt, enter C:\Test.txt. - In the second text box, enter a word or phrase for the application to search for in the text file.
- Click the
Startbutton. TheLinesCountedbutton should begin incrementing immediately. The application displays the message "Finished Counting" when it is done.
To test the Cancel button
- Press F5 to start the application, and enter the file name and search word as described in the previous procedure. Make sure that the file you choose is large enough so you will have time to cancel the procedure before it is finished.
- Click the
Startbutton to start the application. - Click the
Cancelbutton. The application should stop counting immediately.
Error Handling
This application contains some basic error handling. It detects and handles source file problems and blank search strings. You can make this program more robust by handling other errors, such as exceeding the maximum number of words or lines that can be counted.
See Also
Multithreading in Visual Basic .NET | Walkthrough: Authoring a Simple Multithreaded Component with Visual Basic