Aracılığıyla paylaş


İ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:

Kullanıcı arabirimi oluşturmak için

  1. Yeni bir açmak Visual Basic ya da C# Windows proje ve adlı bir form oluşturma uygulama Form1.

  2. İki düğme ve dört metin kutularına eklemek Form1.

  3. 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"

  4. 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

  1. Eklemek bir BackgroundWorker den bileşen bileşenleri bölümünü araç forma.Bu formun bileşen tepsisinde görünür.

  2. 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

  3. 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

  1. 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.

  2. Seçin sınıfı Şablonları penceresinde ve türü Words.vb veya Words.cs ad alanında.

  3. Ekle‘yi tıklatın.Words Class görüntülenir.

  4. 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

  1. 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);
    }
    
  2. 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

  1. F5 tuşuna basarak uygulamayı çalıştırın.

  2. 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.

  3. İkinci metin kutusuna bir sözcük veya tümcecik metin dosyasında aramak uygulamanın girin.

  4. ' 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

  1. 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.

  2. ' I Start uygulamayı başlatmak için düğme.

  3. ' 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)

Diğer Kaynaklar

İş Parçacığı Oluşturma (C# ve Visual Basic)