vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Top-Preis! AP-Access-Tools-CD Volume 1  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Newsletter  | Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2015
 
zurück
Rubrik: Verschiedenes / Sonstiges   |   VB-Versionen: VB.NET07.02.06
Multithreading mit VB.NET 2005

Asynchrone Dateioperationen mit Multithreading verwirklichen

Autor:   Stefan MährBewertung:     [ Jetzt bewerten ]Views:  31.159 
www.visualsoft-net.deSystem:  WinNT, Win2k, WinXP, Vista, Win7, Win8, Win10 Beispielprojekt auf CD 

Summer-Special bei Tools & Components!
Gute Laune Sommer bei Tools & Components
Top Summer-Special - Sparen Sie teilweise über 100,- EUR
Alle sev-Entwicklerkomponenten und Komplettpakete jetzt bis zu 25% reduziert!
zum Beispiel:
  • Developer CD nur 455,- EUR statt 569,- EUR
  • sevDTA 2.0 nur 224,30 EUR statt 299,- EUR
  •  
  • vb@rchiv   Vol.6 nur 18,70 EUR statt 24,95 EUR
  • sevCoolbar 3.0 nur 58,70 EUR statt 69,- EUR
  • - Werbung -Und viele weitere Angebote           Aktionspreise nur für kurze Zeit gültig

    Mit .NET brachte Microsoft den heiligen Gral des Mutlithreadings zu den VB Programmierern. Bis dahin mußten wir uns mit DoEvents vor UI Lockups bewahren, oder noch schlimmer Out Of Process ActiveX-Exen programmieren um diese zu verhinden. Programmieren mit Threads bringt jedoch neue Probleme mit sich wie Deadlocks, nicht mehr ansprechbare Controls da diese in einem anderen Thread laufen usw.

    Dieses kleine VB.NET 2005 Beispiel sollte einen kleinen übersichtlichen Einstieg in das Programmieren mit dem Backgroundworkerthread bieten. Das Beispiel sollte eine große Datei byteweise in einem eigenen Thread kopieren und dabei einen Progress darstellen. Die Operation sollte natürlich jederzeit abbrechbar sein.

    Dazu legen wir ein neues Windowsformsprojekt an und legen folgende Controls auf Form1:

    • 2 x Label (lblSource, lblTarget)
    • 4 x CommandButton (cmdSelectSource, cmdSelectTarget, cmdCancel, cmdCopyAsync)
    • 1 x Statusstrip (Statusstrip1, darauf eine progressbar - progress und einen toolstripstatuslabel)
    • 1 x Textbox (txtTest), mit der beweisen wir das die UI nicht einfriert

    Nun zum Code:
    Wir importieren folgende Namespaces:

    Imports System.IO
    Imports System.ComponentModel

    Private Variablen:

    ' unser Thread
    Private th As BackgroundWorker 
     
    ' wieviele Bytes wurden kopiert
    Private lngBytesCopied As Long 
     
    ' Die Speicheradresse der Zieldatei
    Private lngSourceFileLength As Long

    Die Ladeprozedur des Formulares:
    Hier richten wir den Backgroundworkerthread ein und stellen den Status der UI her.

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
      th = New BackgroundWorker
      AddHandler th.DoWork, AddressOf th_DoWork
      AddHandler th.RunWorkerCompleted, AddressOf th_Completed
      AddHandler th.ProgressChanged, AddressOf th_ProgressChanged				
      th.WorkerReportsProgress = True
      th.WorkerSupportsCancellation = True
     
      Me.lblSource.Text = "<Source File>"
      Me.lblTarget.Text = "<Target File>"
      Me.cmdCopyAsync.Enabled = False
      Me.cmdCancel.Enabled = False
      Me.progress.Visible = False
      Me.lblProgress.Visible = False
    End Sub

    Die Routinen für das Auswählen der Source und Zieldatei. Eigentlich selbsterklärend.

    Private Sub cmdSelectSource_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles cmdSelectSource.Click
     
      Dim openDlg As New OpenFileDialog
      With openDlg
        .Title = "Select file"
        .InitialDirectory = Application.StartupPath
        If .ShowDialog = Windows.Forms.DialogResult.OK Then
          Me.lblSource.Text = .FileName
        End If
      End With
    End Sub
    Private Sub cmdSelectTarget_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles cmdSelectTarget.Click
     
      Dim fldBrowser As New FolderBrowserDialog
      With fldBrowser
        .ShowNewFolderButton = True
        If .ShowDialog = Windows.Forms.DialogResult.OK Then
          Me.lblTarget.Text = .SelectedPath
          Me.cmdCopyAsync.Enabled = True
        End If
      End With
    End Sub

    Hier wird der asnchrone Thread gestartet:

    Private Sub cmdCopyAsync_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles cmdCopyAsync.Click
     
      If Me.lblTarget.Text.Length > 0 And Me.lblSource.Text.Length > 0 Then
        Me.cmdCopyAsync.Enabled = False
        Me.progress.Minimum = 0
        Me.progress.Maximum = 100
        Me.progress.Visible = True
        Me.lblProgress.Visible = True
        Me.cmdCancel.Enabled = True
     
        ' Start des Threads löst dann die th_DoWork Prozedur aus
        th.RunWorkerAsync() 
      End If
    End Sub

    So jetzt das eigentliche Arbeitspferd, die th_DoWork Prozedur kopiert die Datei in einem eigenen Thread.

    Private Sub th_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
      Dim fi As New FileInfo(Me.lblSource.Text)
     
      Dim inStream As FileStream = Nothing
      Dim outStream As FileStream = Nothing
      Dim buffer(2048) As Byte
      Dim offset As Integer = 0				
     
      Try
        inStream = New FileStream(fi.FullName, FileMode.Open)
        outStream = New FileStream(Me.lblTarget.Text & "\" & fi.Name, FileMode.Create)
        lngSourceFileLength = inStream.Length
        Do
          If th.CancellationPending = True Then
            e.Cancel = True
            inStream.Close()
            outStream.Close()
            Exit Sub
          End If
          offset = inStream.Read(buffer, 0, buffer.Length)
          outStream.Write(buffer, 0, offset)
          lngBytesCopied += offset
     
          ' WICHTIG: Hier könen wir einen Progress darstellen
          th.ReportProgress(offset / inStream.Length * 100)
        Loop Until offset = 0
     
      Catch ex As Exception
        MessageBox.Show(ex.Message)
     
      Finally
        inStream.Close()
        outStream.Close()
      End Try
    End Sub

    Jetzt stellen wir den Progress dar.
    Hierzu stellt uns die BackgroundWorker Klasse eine eigene Prozedur zur Verfügung um Threadsafe auf die Controls des Winforms zuzugreifen.

    Private Sub th_ProgressChanged(ByVal sender As Object, _
      ByVal e As ProgressChangedEventArgs)
     
      Try
        Me.lblProgress.Text = lngBytesCopied.ToString & " Bytes From " & _
          lngSourceFileLength.ToString & " Copied"
        Me.progress.Value = e.ProgressPercentage.ToString
      Catch ex As Exception
        MessageBox.Show(ex.Message)
      End Try
    End Sub

    Die Cancel-Operation:

    Private Sub cmdCancel_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles cmdCancel.Click
     
      If th.IsBusy Then
        th.CancelAsync()
      End If
    End Sub

    Wenn der Thread abgeschlossen ist werden wir in der th_completed inklusive Status davon benachrichtigt.

    Private Sub th_Completed(ByVal sender As Object, _
      ByVal e As RunWorkerCompletedEventArgs)
     
      Dim strFinished As String = String.Empty
     
      If e.Cancelled Then
        strFinished = "Operation Cancelled"
      ElseIf e.Error IsNot Nothing Then
        strFinished = "Operation Error " & e.Error.Message
      Else
        strFinished = "Operation Sucessfull"
      End If
     
      MessageBox.Show("CopyThread finished" & vbCrLf & strFinished)
      Me.cmdCopyAsync.Enabled = True
    End Sub

    Noch eine schnelle Sicherheitsüberprüfung, ob der Thread nicht rennt, wenn das Form geschlossen wird.

    Private Sub Form1_FormClosing(ByVal sender As Object, _
      ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
     
      If th.IsBusy Then
        th.CancelAsync()
      End If
    End Sub

    Man kann das Weiterlaufen der UI schön beobachten, indem man einfach während der Copy-Operation einen Text in die Textbox "txtTest" eingibt.

    Dieser Tipp wurde bereits 31.159 mal aufgerufen.

    Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

    Über diesen Tipp im Forum diskutieren
    Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

    Neue Diskussion eröffnen

    nach obenzurück


    Anzeige

    Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
    (einschl. Beispielprojekt!)

    Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
    - nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
    - Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
    Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
     
       

    Druckansicht Druckansicht Copyright ©2000-2015 vb@rchiv Dieter Otter
    Alle Rechte vorbehalten.
    Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

    Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel