İzlenecek yol: BackgroundWorker Bileşeni ile Çoklu İş Parçacığı Kullanımı (C# ve Visual Basic)
Bu izlenecek yolda, bir sözcüğün geçtiği için bir metin dosyası arar çok iş parçacıklı bir uygulama oluşturmak gösterilmiştir.Bunu göstermektedir:
Bir sınıf olarak adlandırılan bir yöntemle tanımlama BackgroundWorker bileşeni.
Tarafından harekete geçirilen olay işleme BackgroundWorker bileşeni.
Başlangıç bir BackgroundWorker bir yöntemi çalıştırmak için Bileşen.
Uygulama bir Cancel durur düğmesini BackgroundWorker bileşeni.
Kullanıcı arabirimi oluşturmak için
Yeni bir açmak Visual Basic ya da C# Windows proje ve adlı bir form oluşturma uygulama Form1.
İki düğme ve dört metin kutularına eklemek Form1.
Nesneler, aşağıdaki tabloda gösterildiği şekilde adlandırın.
Nesne
Özellik
Ayar
İlk düğmeyi
Name, Text
Start, Start
İkinci düğmeyi
Name, Text
İptal, iptal
Birinci metin kutusu
Name, Text
SourceFile, ""
İkinci metin kutusu
Name, Text
CompareString, ""
Üçüncü metin kutusu
Name, Text
WordsCounted, "0"
Dördüncü metin kutusu
Name, Text
LinesCounted, "0"
Her metin kutusunun yanında bir etiket ekleyin.Set Text özelliği aşağıdaki tabloda gösterildiği gibi her etiket için.
Nesne
Özellik
Ayar
İlk etiketin
Text
Kaynak dosyası
İkinci etiketi
Text
Dize karşılaştırma
Üçüncü label
Text
Eşleşen sözcükleri
Dördüncü label
Text
Sayılan satırları
BackgroundWorker bileşeni oluşturmak ve onun olaylara abone olmak için
Eklemek bir BackgroundWorker den bileşen bileşenleri bölümünü araç forma.Bu formun bileşen tepsisinde görünür.
BackgroundWorker1 nesnesi için aşağıdaki özellikleri ayarlayın Visual Basic ya da C# [NULL]'ta backgroundWorker1 nesnesi.
Özellik
Ayar
WorkerReportsProgress
True
WorkerSupportsCancellation
True
C# [NULL]'ta yalnızca backgroundWorker1 nesnesinin olaylarına abone olun.Üstündeki özelliklerini penceresinde tıklatın olaylar simgesi.Çift RunWorkerCompleted olayı, bir olay işleyicisi yöntemi yaratın.Aynı yapmak ProgressChanged ve DoWork olayları.
Ayrı bir iş parçacığı üzerinde çalışacak yöntemi tanımlamak için
Dan Proje menüsünden seçin Add Class bir sınıf projeye eklemek için.Yeni Öğe Ekle iletişim kutusu görüntülenir.
Seçin sınıfı Şablonları penceresinde ve türü Words.vb veya Words.cs ad alanında.
Ekle‘yi tıklatın.Words Class görüntülenir.
Aşağıdaki kodu Words sınıfına ekleyin:
Public Class Words ' Object to store the current state, for passing to the caller. Public Class CurrentState Public LinesCounted As Integer Public WordsMatched As Integer End Class Public SourceFile As String Public CompareString As String Private WordCount As Integer = 0 Private LinesCounted As Integer = 0 Public Sub CountWords( ByVal worker As System.ComponentModel.BackgroundWorker, ByVal e As System.ComponentModel.DoWorkEventArgs ) ' Initialize the variables. Dim state As New CurrentState Dim line = "" Dim elapsedTime = 20 Dim lastReportDateTime = Now If CompareString Is Nothing OrElse CompareString = System.String.Empty Then Throw New Exception("CompareString not specified.") End If Using myStream As New System.IO.StreamReader(SourceFile) ' Process lines while there are lines remaining in the file. Do While Not myStream.EndOfStream If worker.CancellationPending Then e.Cancel = True Exit Do Else line = myStream.ReadLine WordCount += CountInString(line, CompareString) LinesCounted += 1 ' Raise an event so the form can monitor progress. If Now > lastReportDateTime.AddMilliseconds(elapsedTime) Then state.LinesCounted = LinesCounted state.WordsMatched = WordCount worker.ReportProgress(0, state) lastReportDateTime = Now End If ' Uncomment for testing. 'System.Threading.Thread.Sleep(5) End If Loop ' Report the final count values. state.LinesCounted = LinesCounted state.WordsMatched = WordCount worker.ReportProgress(0, state) End Using End Sub Private Function CountInString( ByVal SourceString As String, ByVal CompareString As String ) As Integer ' This function counts the number of times ' a word is found in a line. If SourceString Is Nothing Then Return 0 End If Dim EscapedCompareString = System.Text.RegularExpressions.Regex.Escape(CompareString) ' To count all occurrences of the string, even within words, remove ' both instances of "\b". Dim regex As New System.Text.RegularExpressions.Regex( "\b" + EscapedCompareString + "\b", System.Text.RegularExpressions.RegexOptions.IgnoreCase) Dim matches As System.Text.RegularExpressions.MatchCollection matches = regex.Matches(SourceString) Return matches.Count End Function End Class
public class Words { // Object to store the current state, for passing to the caller. public class CurrentState { public int LinesCounted; public int WordsMatched; } public string SourceFile; public string CompareString; private int WordCount; private int LinesCounted; public void CountWords( System.ComponentModel.BackgroundWorker worker, System.ComponentModel.DoWorkEventArgs e) { // Initialize the variables. CurrentState state = new CurrentState(); string line = ""; int elapsedTime = 20; DateTime lastReportDateTime = DateTime.Now; if (CompareString == null || CompareString == System.String.Empty) { throw new Exception("CompareString not specified."); } // Open a new stream. using (System.IO.StreamReader myStream = new System.IO.StreamReader(SourceFile)) { // Process lines while there are lines remaining in the file. while (!myStream.EndOfStream) { if (worker.CancellationPending) { e.Cancel = true; break; } else { line = myStream.ReadLine(); WordCount += CountInString(line, CompareString); LinesCounted += 1; // Raise an event so the form can monitor progress. int compare = DateTime.Compare( DateTime.Now, lastReportDateTime.AddMilliseconds(elapsedTime)); if (compare > 0) { state.LinesCounted = LinesCounted; state.WordsMatched = WordCount; worker.ReportProgress(0, state); lastReportDateTime = DateTime.Now; } } // Uncomment for testing. //System.Threading.Thread.Sleep(5); } // Report the final count values. state.LinesCounted = LinesCounted; state.WordsMatched = WordCount; worker.ReportProgress(0, state); } } private int CountInString( string SourceString, string CompareString) { // This function counts the number of times // a word is found in a line. if (SourceString == null) { return 0; } string EscapedCompareString = System.Text.RegularExpressions.Regex.Escape(CompareString); System.Text.RegularExpressions.Regex regex; regex = new System.Text.RegularExpressions.Regex( // To count all occurrences of the string, even within words, remove // both instances of @"\b" from the following line. @"\b" + EscapedCompareString + @"\b", System.Text.RegularExpressions.RegexOptions.IgnoreCase); System.Text.RegularExpressions.MatchCollection matches; matches = regex.Matches(SourceString); return matches.Count; } }
İş parçacığı olayları işlemek için
Ana form için aşağıdaki olay işleyicisini ekleyin:
Private Sub BackgroundWorker1_RunWorkerCompleted( ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs ) Handles BackgroundWorker1.RunWorkerCompleted ' This event handler is called when the background thread finishes. ' This method runs on the main thread. If e.Error IsNot Nothing Then MessageBox.Show("Error: " & e.Error.Message) ElseIf e.Cancelled Then MessageBox.Show("Word counting canceled.") Else MessageBox.Show("Finished counting words.") End If End Sub Private Sub BackgroundWorker1_ProgressChanged( ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs ) Handles BackgroundWorker1.ProgressChanged ' This method runs on the main thread. Dim state As Words.CurrentState = CType(e.UserState, Words.CurrentState) Me.LinesCounted.Text = state.LinesCounted.ToString Me.WordsCounted.Text = state.WordsMatched.ToString End Sub
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // This event handler is called when the background thread finishes. // This method runs on the main thread. if (e.Error != null) MessageBox.Show("Error: " + e.Error.Message); else if (e.Cancelled) MessageBox.Show("Word counting canceled."); else MessageBox.Show("Finished counting words."); } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { // This method runs on the main thread. Words.CurrentState state = (Words.CurrentState)e.UserState; this.LinesCounted.Text = state.LinesCounted.ToString(); this.WordsCounted.Text = state.WordsMatched.ToString(); }
WordCount yöntemi bir çalışan başlatın ve yeni bir iş parçacığı çağırmak için
Aşağıdaki yordamlarda, programınıza ekleyin:
Private Sub BackgroundWorker1_DoWork( ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs ) Handles BackgroundWorker1.DoWork ' This event handler is where the actual work is done. ' This method runs on the background thread. ' Get the BackgroundWorker object that raised this event. Dim worker As System.ComponentModel.BackgroundWorker worker = CType(sender, System.ComponentModel.BackgroundWorker) ' Get the Words object and call the main method. Dim WC As Words = CType(e.Argument, Words) WC.CountWords(worker, e) End Sub Sub StartThread() ' This method runs on the main thread. Me.WordsCounted.Text = "0" ' Initialize the object that the background worker calls. Dim WC As New Words WC.CompareString = Me.CompareString.Text WC.SourceFile = Me.SourceFile.Text ' Start the asynchronous operation. BackgroundWorker1.RunWorkerAsync(WC) End Sub
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { // This event handler is where the actual work is done. // This method runs on the background thread. // Get the BackgroundWorker object that raised this event. System.ComponentModel.BackgroundWorker worker; worker = (System.ComponentModel.BackgroundWorker)sender; // Get the Words object and call the main method. Words WC = (Words)e.Argument; WC.CountWords(worker, e); } private void StartThread() { // This method runs on the main thread. this.WordsCounted.Text = "0"; // Initialize the object that the background worker calls. Words WC = new Words(); WC.CompareString = this.CompareString.Text; WC.SourceFile = this.SourceFile.Text; // Start the asynchronous operation. backgroundWorker1.RunWorkerAsync(WC); }
Call StartThread yönteminden Start formunuzda düğmesi:
Private Sub Start_Click() Handles Start.Click StartThread() End Sub
private void Start_Click(object sender, EventArgs e) { StartThread(); }
İş parçacığı durduran iptal düğmesi uygulamak için
Call StopThread yordam Click olay işleyicisi Cancel düğme.
Private Sub Cancel_Click() Handles Cancel.Click ' Cancel the asynchronous operation. Me.BackgroundWorker1.CancelAsync() End Sub
private void Cancel_Click(object sender, EventArgs e) { // Cancel the asynchronous operation. this.backgroundWorker1.CancelAsync(); }
Sınama
Şimdi düzgün çalıştığından emin olmak için uygulamayı test edebilirsiniz.
Uygulamayı test etmek için
F5 tuşuna basarak uygulamayı çalıştırın.
Form görüntülendiğinde, sınamak istediğiniz dosya için dosya yolunu girin sourceFile kutusu.Örneğin, sınama dosyanızı sınama.txt adlı varsayarsak, C:\Test.txt girin.
İkinci metin kutusuna bir sözcük veya tümcecik metin dosyasında aramak uygulamanın girin.
' I Start düğme.LinesCounted Düğmesini hemen artırma başlamak.Bu yapıldığında uygulama "sayım tamamlandı" iletisi görüntüler.
İptal düğmesi sınamak için
Uygulamasını başlatın ve önceki yordamda açıklandığı gibi dosya adı ve arama sözcüğü girmek için F5 tuşuna basın.Seçtiğiniz dosya yordamı tamamlanmadan önce iptal etmek için zaman olacaktır emin olmak için yeterli büyüklükte olduğundan emin olun.
' I Start uygulamayı başlatmak için düğme.
' I Cancel düğme.Uygulama, hemen sayım durdurmanız gerekir.
Sonraki Adımlar
Bu uygulama bazı temel hata işleme içerir.Boş dizeleri algıladığı.Sözcükleri veya sayılması satırları en fazla sayısını aşan gibi diğer hataları ele alarak, bu programı daha güçlü duruma getirebilirsiniz.
Ayrıca bkz.
Görevler
İzlenecek yol: Visual Basic İle Temel Bir Çok İş Parçacıklı Bileşen Yazma
Nasıl yapılır: Olaylara Abone Olma ve Aboneliği Kaldırma (C# Programlama Kılavuzu)