Projekt do pobrania tutaj: ProgressBar_BackGrW
Pokażę wam jak zrobić takie cudeńko które będzie kopiowało nam plik z punktu A do punktu B z możliwością anulowania kopiowania i z BackgroundWorkerem. Zaczynamy od dodania do naszej formy 4x Buttonów 3x Label i 1x ProgressBar
Kiedy ułożymy wszystkie kontrolki należ zmienić im tekst, Labele mają tekst „-”
Teraz z ToolBoxa potrzebujemy elementów: OpenFileDialog, BackgroundWorker, FolderBrowserDialog
Jeśli wszystko przebiegło prawidłowo na dole ekranu zobaczymy dodane elementy
Lewym przyciskiem myszy klikamy na element „BackgroundWorker1” i ustawiamy mu opcje WorkerReportsProgress na True i WorkerSupportsCancell na True
Teraz dodamy aktywność do przycisków wskazujących położenie pliku i miejsca docelowego kopii są to Button1 (Target file) i Button2 (Destiny directory)
Dim fileTargetLocation As String 'Zmienna przechowuje ścieżkę do pliku
Dim Destinydirectory As String 'Zmienna przechowuje folder docelowy kopii
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Wywołanie dialogu wskazującego ścieżkę do pliku
OpenFileDialog1.Title = "Select a file to copy"
OpenFileDialog1.FileName = ""
With OpenFileDialog1
If .ShowDialog() = DialogResult.OK Then
fileTargetLocation = .FileName 'załadowanie ścieżki do zmiennej
Label1.Text = fileTargetLocation.ToString
End If
End With
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
'Wywołanie dialogu wskazującego folder docelowy
FolderBrowserDialog1.Description = "Select destiny directory"
With FolderBrowserDialog1
If .ShowDialog() = DialogResult.OK Then
Destinydirectory = .SelectedPath 'załadowanie ścieżki do zmiennej
Label2.Text = Destinydirectory.ToString
End If
End With
End Sub
Reszta kodu wraz z opisem. Dodaje funkcjonalność dla reszty przycisków i BackgroundWorkera
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) _
Handles BackgroundWorker1.DoWork
Dim parts As String() = fileTargetLocation.Split(New Char() {"\"c}) 'Dzieli plik
Dim filename As String = parts(parts.Count - 1) 'pobiera z podzielonego pliku tylko nazwę pliku który kopiujemy
Dim streamRead As New System.IO.FileStream(fileTargetLocation, System.IO.FileMode.Open) 'Otwiera nasz plik
Dim streamWrite As New System.IO.FileStream(Destinydirectory + "\" + filename,
IO.FileMode.Create,
IO.FileAccess.Write,
IO.FileShare.None) 'określa lokalizację docelową pliku i jego właściwości
Dim lngLen As Long = streamRead.Length - 1
Dim byteBuffer(4096) As Byte 'inicjujemy buffer
Dim intBytesRead As Integer
'If we use Async we need to Invoke
setLabelTxt("Copy bytes : (0/" + (lngLen * 100).ToString + ")", Label3) 'Wyświetla ilość skopiowanych bytów
'Pętla kopii
While streamRead.Position < lngLen
If (BackgroundWorker1.CancellationPending = True) Then 'Przerywa wykonywanie BackgroundWorkera
e.Cancel = True
Exit While
End If
'ładuje poziom na jakim jest kopiowanie do BackgroundWorker-Progress
BackgroundWorker1.ReportProgress(CInt(streamRead.Position / lngLen * 100))
setLabelTxt("Copy bytes : (" + CInt(streamRead.Position).ToString + "/" +
(lngLen * 100).ToString + ")", Label3) 'Wyświetla stan kopiowania w bytach
intBytesRead = (streamRead.Read(byteBuffer, 0, 4096))
streamWrite.Write(byteBuffer, 0, intBytesRead) 'Zapisuje na dysku
End While
streamWrite.Flush()
streamWrite.Close()
streamRead.Close()
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Button1.Enabled = False 'blokuje przycisk 1
Button2.Enabled = False 'blokuje przycisk 2
BackgroundWorker1.RunWorkerAsync() 'wywołuje BackgroundWorkera, startuje go
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) _
Handles BackgroundWorker1.ProgressChanged
ProgressBar1.Value = e.ProgressPercentage 'Wyświetla stan kopiowania
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) _
Handles BackgroundWorker1.RunWorkerCompleted
If e.Cancelled = True Then 'komunikaty i elementy wykonywalny po ukończeniu kopii bądź jej przerwaniu
MsgBox("Copy canceled!")
Else
MsgBox("Copy complete!")
End If
Button1.Enabled = True
Button2.Enabled = True
End Sub
'Wymagany sposób odwolywania się do formy podczas wykonywania działań asynchwonicznych takich jak BackgroundWorker
Private Sub setLabelTxt(ByVal text As String, ByVal lbl As Label)
If lbl.InvokeRequired Then
lbl.Invoke(New setLabelTxtInvoker(AddressOf setLabelTxt), text, lbl)
Else
lbl.Text = text
End If
End Sub
Private Delegate Sub setLabelTxtInvoker(ByVal text As String, ByVal lbl As Label)
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
If BackgroundWorker1.IsBusy Then ' przerywa wykonywanie BackgroundWorkera
BackgroundWorker1.CancelAsync()
End If
End Sub

