This code sample assumes that the form has the following controls on it:( 需要的控件:) TextBox called txtSearchPath TextBox called txtSearchPattern Label called lblMessage Button called btnStart 注意这个按钮的.text属性为:“Start” ListBox called lstFiles
Imports System.IO PublicClass SearchFilesFrmClass SearchFilesFrm ' To set up for a background operation, add an event handler for the DoWork event. ' Call your time-consuming operation in this event handler. To start the operation, ' call RunWorkerAsync. To receive notifications of progress updates, handle the ' ProgressChanged event. To receive a notification when the operation is completed, ' handle the RunWorkerCompleted event. ' Note ' You must be careful not to manipulate any user-interface objects in your DoWork ' event handler. Instead, communicate to the user interface through the ' ProgressChanged and RunWorkerCompleted events. ' If your background operation requires a parameter, call RunWorkerAsync with your ' parameter. Inside the DoWork event handler, you can extract the parameter from ' the DoWorkEventArgs.Argument property. ' Store the results of the search Private Files As List(OfString) ' Used to prevent nested calls to ProgressChanged Private CallInProgress AsBoolean ' The Worker thread PrivateWithEvents BgWorker AsNew System.ComponentModel.BackgroundWorker PrivateSub SearchFilesFrm_Load()Sub SearchFilesFrm_Load(ByVal sender AsObject, _ ByVal e As System.EventArgs) HandlesMe.Load ' Enable ProgressChanged and Cancellation mothed BgWorker.WorkerReportsProgress =True BgWorker.WorkerSupportsCancellation =True End Sub ' Start and Stop the search PrivateSub btnStart_Click()Sub btnStart_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnStart.Click If btnStart.Text ="Start"Then IfNot Directory.Exists(txtSearchPath.Text.Trim()) Then MessageBox.Show("The Search Directory does not exist", _ "Path Error", MessageBoxButtons.OK, MessageBoxIcon.Error) Return EndIf If txtSearchPattern.Text.Trim() =""Then txtSearchPattern.Text ="*" Dim arguments() AsString= {txtSearchPath.Text.Trim(), _ txtSearchPattern.Text.Trim()} lstFiles.Items.Clear() ' Start the background worker thread. Thread runs in DoWork event. BgWorker.RunWorkerAsync(arguments) btnStart.Text ="Stop" Else BgWorker.CancelAsync() EndIf End Sub ' Start the Asynchronous file search. The background thread does it work from ' this event. PrivateSub BgWorker_DoWork()Sub BgWorker_DoWork(ByVal sender AsObject, _ ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BgWorker.DoWork 'Retrieve the search path which was requested Dim path AsString=DirectCast(e.Argument, String())(0) Dim pattern AsString=DirectCast(e.Argument, String())(1) ' Invoke the worker procedure Files =New List(OfString) SearchFiles(path, pattern) ' Return a result to the RunWorkerCompleted event Dim message AsString=String.Format("Found {0} Files", Files.Count) e.Result = message End Sub ' Recursively search directory and sub directories PrivateSub SearchFiles()Sub SearchFiles(ByVal path AsString, ByVal pattern AsString) ' Displat message Dim message AsString=String.Format("Parsing Directory {0}", path) BgWorker.ReportProgress(0, message) 'Read the files and if the Stop button is pressed cancel the operation ForEach fileName AsStringIn Directory.GetFiles(path, pattern) If BgWorker.CancellationPending ThenReturn Files.Add(fileName) Next ForEach dirName AsStringIn Directory.GetDirectories(path) If BgWorker.CancellationPending ThenReturn SearchFiles(dirName, pattern) Next End Sub ' The bacground thread calls this event when you make a call to ReportProgress ' It is OK to access user controls in the UI from this event. ' If you use a Progress Bar or some other control to report the tasks progress ' you should avoid unnecessary calls to ReportProgress method because this causes ' a thread switch which is a relatively expensive in terms of processing time. PrivateSub BgWorker_ProgressChanged()Sub BgWorker_ProgressChanged(ByVal sender AsObject, _ ByVal e As System.ComponentModel.ProgressChangedEventArgs) _ Handles BgWorker.ProgressChanged ' Reject a nested call. If CallInProgress ThenReturn CallInProgress =True ' Display the message received in the UserState property lblMessage.Text = e.UserState.ToString() ' Display all files added since last call. For idx AsInteger= lstFiles.Items.Count To Files.Count -1 lstFiles.Items.Add(Files(idx)) Next ' If a Me.Refresh is in this code you will need to place a Application.DoEvents() ' otherwise the UI will not respond without them it works fine. ' Me.Refresh() ' Let the Windows OS process messages in the queue ' Application.DoEvents() CallInProgress =False End Sub ' The background thread calls this event just before it reaches the End Sub ' of the DoWork event. It is OK to access user controls in the UI from this event. PrivateSub BgWorker_RunWorkerCompleted()Sub BgWorker_RunWorkerCompleted(ByVal sender AsObject, _ ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _ Handles BgWorker.RunWorkerCompleted ' Display the last message and reset the Start/Stop button text lblMessage.Text = e.Result.ToString() btnStart.Text ="Start" End Sub End Class