Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Drawing
Imports System.Threading
Imports System.Windows.Forms

Public Class FibonacciForm

    Private Sub startAsyncButton_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles startAsyncButton.Click

        ' Wyłączamy przycisk Start do czasu 
        ' zakończenia operacji asynchronicznej
        startAsyncButton.Enabled = False

        ' Włączamy przycisk Anuluj na czas 
        ' trwania operacji asynchronicznej
        cancelAsyncButton.Enabled = True

        ' Uruchamiamy operację asynchroniczną
        backgroundWorker1.RunWorkerAsync(Int32.Parse(txtWaitTime.Text))
    End Sub

    ' W tej procedurze obsługi zdarzenia wykonywana jest właściwa operacja
    Private Sub backgroundWorker1_DoWork( _
      ByVal sender As Object, _
      ByVal e As DoWorkEventArgs) Handles backgroundWorker1.DoWork

        ' Pobieramy dostarczone informacje
        Dim Worker As BackgroundWorker = CType(sender, BackgroundWorker)

        Dim StartTime As DateTime = DateTime.Now
        Dim SecondsToWait As Integer = CType(e.Argument, Integer)
        Dim Answer As Single = 100
        Do
            ' Sprawdzamy, czy nie zażądano anulowania
            If Worker.CancellationPending Then
                e.Cancel = True
                Return
            End If

            ' Kontynuujemy obliczanie wyniku
            Answer *= 1.01

            ' Raportujemy postępy (procent wykonania)
            Worker.ReportProgress(( _
              DateTime.Now.Subtract(StartTime).TotalSeconds / SecondsToWait) * 100)

            Thread.Sleep(50)

        Loop Until DateTime.Now > (StartTime.AddSeconds(SecondsToWait))

        e.Result = Answer

    End Sub

    ' Ta procedura obsługi zdarzenia jest wywoływana
    ' po zakończeniu drugoplanowej operacji
    Private Sub backgroundWorker1_RunWorkerCompleted( _
      ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) _
      Handles backgroundWorker1.RunWorkerCompleted

        ' Sprawdzamy wynik i aktualizujemy formularz
        If Not (e.Error Is Nothing) Then
            ' Zgłoszony został wyjątek
            MessageBox.Show(e.Error.Message)
        ElseIf e.Cancelled Then
            ' Sprawdzamy, czy użytkownik anulował operację
            result.Text = "Anulowano"
        Else
            ' Operacja powiodła się
            result.Text = "Wynik: " & e.Result.ToString()
        End If

        startAsyncButton.Enabled = True
        cancelAsyncButton.Enabled = False
    End Sub

    ' Ta procedura obsługi zdarzenia aktualizuje pasek postępu
    Private Sub backgroundWorker1_ProgressChanged( _
      ByVal sender As Object, ByVal e As ProgressChangedEventArgs) _
      Handles backgroundWorker1.ProgressChanged

        Me.progressBar1.Value = e.ProgressPercentage
    End Sub

    Private Sub cancelAsyncButton_Click( _
      ByVal sender As System.Object, ByVal e As System.EventArgs) _
      Handles cancelAsyncButton.Click


        ' Anulujemy operację asynchroniczną
        Me.backgroundWorker1.CancelAsync()

        cancelAsyncButton.Enabled = False

    End Sub

End Class
