Imports System.ComponentModel
Imports System.Drawing

Public Class Form1

    ' 23-12-2010    First Release
    ' 28-12-2010   Added sub init


    Public x(10, 10), y(10, 10), z(10, 10)
    Public itercnt(5), seccnt(5) As Integer
    Public npreq, np As Integer
    Public state(5) As Integer
    Public loadreq, loadd As Integer   ' Name Load cannot be used !
    Const StartSt As Integer = 1, StopSt As Integer = 0, CancelSt As Integer = 3, Endst = 0

    Public Sub New()
        InitializeComponent()
        InitForm()

        BackgroundWorkerpp1.WorkerReportsProgress = True
        BackgroundWorkerpp1.WorkerSupportsCancellation = True
        BackgroundWorkerpp2.WorkerReportsProgress = True
        BackgroundWorkerpp2.WorkerSupportsCancellation = True
        BackgroundWorkerpp3.WorkerReportsProgress = True
        BackgroundWorkerpp3.WorkerSupportsCancellation = True
        BackgroundWorkerpp4.WorkerReportsProgress = True
        BackgroundWorkerpp4.WorkerSupportsCancellation = True
        BackgroundWorkerpp5.WorkerReportsProgress = True
        BackgroundWorkerpp5.WorkerSupportsCancellation = True
        ResultLabelpp1.Text = " "
        ResultLabelpp2.Text = " "
        ResultLabelpp3.Text = " "
        ResultLabelpp4.Text = " "
        ResultLabelpp5.Text = " "
    End Sub

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

        Dim a As String

        If BackgroundWorkerpp1.IsBusy <> True Then
            ' Start the asynchronous operation.
            BackgroundWorkerpp1.RunWorkerAsync()
            npreq = 1
            ProcTpp1.Text = 1
        Else
            If BackgroundWorkerpp2.IsBusy <> True Then
                ' Start the asynchronous operation.
                BackgroundWorkerpp2.RunWorkerAsync()
                npreq = 2
                ProcTpp2.Text = 2
            Else
                If BackgroundWorkerpp3.IsBusy <> True Then
                    ' Start the asynchronous operation.
                    BackgroundWorkerpp3.RunWorkerAsync()
                    npreq = 3
                    ProcTpp3.Text = 3
                Else
                    If BackgroundWorkerpp4.IsBusy <> True Then
                        ' Start the asynchronous operation.
                        BackgroundWorkerpp4.RunWorkerAsync()
                        npreq = 4
                        ProcTpp4.Text = 4
                    Else
                        If BackgroundWorkerpp5.IsBusy <> True Then
                            ' Start the asynchronous operation.
                            BackgroundWorkerpp5.RunWorkerAsync()
                            npreq = 5
                            ProcTpp5.Text = 5
                        End If

                    End If

                End If

            End If

        End If
        NProcT.Text = npreq

        a = loadT.Text : loadreq = Val(a)
        If loadreq = 0 Then loadreq = 1

    End Sub

    Private Sub cancelAsyncButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CancelAsyncButton.Click
        Dim a As String

        If npreq = 0 Then Exit Sub

        ' Update control panel
        If npreq = 1 Then
            ProcTpp1.Text = " "
        Else
            If npreq = 2 Then
                ProcTpp2.Text = " "
            Else
                If npreq = 3 Then
                    ProcTpp3.Text = " "
                Else
                    If npreq = 4 Then
                        ProcTpp4.Text = " "
                    Else
                        ProcTpp5.Text = " "
                    End If
                End If
            End If
        End If

        npreq = npreq - 1
        NProcT.Text = npreq
        a = loadT.Text : loadreq = Val(a)
        If loadreq = 0 Then loadreq = 1

    End Sub

    Private Sub EndSyncButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles EndAsyncButton.Click

        If npreq > 0 Then
            Debug.Print("Click End" + Str(npreq))
            npreq = -1                                     ' npreq end state
        Else
            End
        End If

    End Sub

    Private Sub MonitorButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MonitorButton.Click

        StateTpp1.Text = state(1)
        StateTpp2.Text = state(2)
        StateTpp3.Text = state(3)
        StateTpp4.Text = state(4)
        StateTpp5.Text = state(5)

    End Sub



    ' This event handler 1 is where the time-consuming work is done.
    Private Sub backgroundWorker1_DoWork(ByVal sender As System.Object, _
    ByVal e As DoWorkEventArgs) Handles BackgroundWorkerpp1.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        Dim i, j, pstr, ip As Integer
        Dim sec1, sec2 As Integer
        Dim a As String
        sec1 = Second(Now)
        pstr = 0                            ' Processor start = 1-1
        a = loadT.Text : loadreq = Val(a)       ' Load loop counter
        If loadreq = 0 Then loadreq = 1
        Debug.Print("PP1 Load " + Str(loadreq))

        Init()

        Do
            itercnt(1) = itercnt(1) + 1
            If np <> npreq Then
                If npreq = -1 Then                  ' end state
                    If np > 0 Then
                        state(np) = CancelSt
                        np = np - 1
                    Else
                        npreq = 0
                        End
                    End If
                Else
                    If npreq < np Then
                        state(np) = CancelSt
                    End If
                    np = npreq        ' make local - Only P1
                End If
                For i = 0 To 5
                    itercnt(i) = -1 : seccnt(i) = -1
                Next
                loadd = loadreq
            End If
            If np > 1 Then state(2) = StartSt ' Start P1
            If np > 2 Then state(3) = StartSt ' start p2
            If np > 3 Then state(4) = StartSt ' Start P3
            If np > 4 Then state(5) = StartSt ' Start P3
            If np > 0 Then
                For ip = 1 To loadd
                    For i = pstr To 10 Step np
                        For j = 0 To 10
                            x(i, j) = y(i, j) + z(i, j)
                        Next
                    Next
                Next ip
            End If

            If np > 1 Then
                Do
                Loop Until state(2) = StopSt
            End If
            If np > 2 Then
                Do
                Loop Until state(3) = StopSt
            End If
            If np > 3 Then
                Do
                Loop Until state(4) = StopSt
            End If
            If np > 4 Then
                Do
                Loop Until state(5) = StopSt
            End If

            ''If (worker.CancellationPending = True) Or state(1) = CancelSt Then
            If state(1) = CancelSt Then
                e.Cancel = True
                state(1) = Endst
                Debug.Print("PP1 Cancelst " + Str(state(1)))
                Exit Sub
            Else
                ' Perform a time consuming operation and report progress.
                sec2 = Second(Now)
                If sec2 <> sec1 Then
                    System.Threading.Thread.Sleep(1)
                    sec1 = Second(Now)
                    seccnt(1) = seccnt(1) + 1
                    If seccnt(1) <= 0 Then
                        itercnt(1) = 0
                        worker.ReportProgress(0)
                    Else
                        worker.ReportProgress(itercnt(1) / seccnt(1))
                    End If
                    'cnt = 0
                End If
            End If
        Loop

    End Sub

    ' This event handler 1 updates the progress.
    Private Sub backgroundWorkerpp1_ProgressChanged(ByVal sender As System.Object, _
    ByVal e As ProgressChangedEventArgs) Handles BackgroundWorkerpp1.ProgressChanged
        ResultLabelpp1.Text = (e.ProgressPercentage.ToString())
        seccntT.Text = Str(seccnt(1))
    End Sub

    ' This event handler 1  deals with the results of the background operation.
    Private Sub backgroundWorkerpp1_RunWorkerCompleted(ByVal sender As System.Object, _
    ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorkerpp1.RunWorkerCompleted
        If e.Cancelled = True Then
            ResultLabelpp1.Text = "Canceled!"
        ElseIf e.Error IsNot Nothing Then
            ResultLabelpp1.Text = "Error: " & e.Error.Message
        Else
            ResultLabelpp1.Text = "Done!"
        End If
    End Sub

    ' This event handler 2 is where the time-consuming work is done.
    Private Sub backgroundWorkerpp2_DoWork(ByVal sender As System.Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorkerpp2.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        Dim i, j, pstr, ip As Integer
        Dim sec1, sec2 As Integer
        sec1 = Second(Now)
        pstr = 1
        Debug.Print("PP2 Load " + Str(2))
        Do
            itercnt(2) = itercnt(2) + 1
            If state(2) = StartSt Then
                For ip = 1 To loadd
                    For i = pstr To 10 Step np
                        For j = 0 To 10
                            x(i, j) = y(i, j) + z(i, j)
                        Next
                    Next
                Next ip
                state(2) = StopSt
            End If
            ' If (worker.CancellationPending = True) Or state(2) = CancelSt Then
            If state(2) = CancelSt Then
                e.Cancel = True
                state(2) = Endst
                Debug.Print("PP2 Cancelst " + Str(state(2)))
                Exit Sub
            Else
                sec2 = Second(Now)
                If sec2 <> sec1 Then
                    System.Threading.Thread.Sleep(1)
                    sec1 = Second(Now)
                    seccnt(2) = seccnt(2) + 1
                    If seccnt(2) <= 0 Then
                        itercnt(2) = 0
                        worker.ReportProgress(0)
                    Else
                        worker.ReportProgress(itercnt(2) / seccnt(2))
                    End If
                End If
            End If
        Loop

    End Sub

    ' This event handler 2 updates the progress.
    Private Sub backgroundWorkerpp2_ProgressChanged(ByVal sender As System.Object, _
    ByVal e As ProgressChangedEventArgs) Handles BackgroundWorkerpp2.ProgressChanged
        ResultLabelpp2.Text = (e.ProgressPercentage.ToString())
    End Sub

    ' This event handler 2 deals with the results of the background operation.
    Private Sub backgroundWorkerpp2_RunWorkerCompleted(ByVal sender As System.Object, _
    ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorkerpp2.RunWorkerCompleted
        If e.Cancelled = True Then
            ResultLabelpp2.Text = "Canceled!"
        ElseIf e.Error IsNot Nothing Then
            ResultLabelpp2.Text = "Error: " & e.Error.Message
        Else
            ResultLabelpp2.Text = "Done!"
        End If
    End Sub

    ' This event handler 3 is where the time-consuming work is done.
    Private Sub backgroundWorkerpp3_DoWork(ByVal sender As System.Object, _
    ByVal e As DoWorkEventArgs) Handles BackgroundWorkerpp3.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        Dim i, j, pstr As Integer
        Dim sec1, sec2 As Integer
        sec1 = Second(Now)
        pstr = 2
        Debug.Print("PP3 Load " + Str(3))
        Do
            itercnt(3) = itercnt(3) + 1
            If state(3) = StartSt Then
                For ip = 1 To loadd
                    For i = pstr To 10 Step np
                        For j = 0 To 10
                            x(i, j) = y(i, j) + z(i, j)
                        Next
                    Next
                Next
                state(3) = StopSt
            End If

            If state(3) = CancelSt Then
                e.Cancel = True
                state(3) = Endst
                Debug.Print("PP3 Cancelst " + Str(state(3)))
                Exit Sub
            Else
                sec2 = Second(Now)
                If sec2 <> sec1 Then
                    System.Threading.Thread.Sleep(1)
                    sec1 = Second(Now)
                    seccnt(3) = seccnt(3) + 1
                    If seccnt(3) <= 0 Then
                        itercnt(3) = 0
                        worker.ReportProgress(0)
                    Else
                        worker.ReportProgress(itercnt(3) / seccnt(3))
                    End If
                End If
            End If
        Loop

    End Sub

    ' This event handler 3 updates the progress.
    Private Sub backgroundWorkerpp3_ProgressChanged(ByVal sender As System.Object, _
    ByVal e As ProgressChangedEventArgs) Handles BackgroundWorkerpp3.ProgressChanged
        ResultLabelpp3.Text = (e.ProgressPercentage.ToString())
    End Sub

    ' This event handler 3 deals with the results of the background operation.
    Private Sub backgroundWorkerpp3_RunWorkerCompleted(ByVal sender As System.Object, _
    ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorkerpp3.RunWorkerCompleted
        If e.Cancelled = True Then
            ResultLabelpp3.Text = "Canceled!"
        ElseIf e.Error IsNot Nothing Then
            ResultLabelpp3.Text = "Error: " & e.Error.Message
        Else
            ResultLabelpp3.Text = "Done!"
        End If
    End Sub


    ' This event handler 4 is where the time-consuming work is done.
    Private Sub backgroundWorkerpp4_DoWork(ByVal sender As System.Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorkerpp4.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        Dim i, j, pstr As Integer
        Dim sec1, sec2 As Integer
        sec1 = Second(Now)
        pstr = 3
        Do
            itercnt(4) = itercnt(4) + 1
            If state(4) = StartSt Then
                For ip = 1 To loadd
                    For i = pstr To 10 Step np
                        For j = 0 To 10
                            x(i, j) = y(i, j) + z(i, j)
                        Next
                    Next
                Next
                state(4) = StopSt
            End If

            'If (worker.CancellationPending = True) Or state(4) = CancelSt Then
            If state(4) = CancelSt Then
                e.Cancel = True
                state(4) = Endst
                Debug.Print("PP4 Cancelst " + Str(state(4)))
                Exit Sub
            Else
                sec2 = Second(Now)
                If sec2 <> sec1 Then
                    System.Threading.Thread.Sleep(1)
                    sec1 = Second(Now)
                    seccnt(4) = seccnt(4) + 1
                    If seccnt(4) <= 0 Then
                        itercnt(4) = 0
                        worker.ReportProgress(0)
                    Else
                        worker.ReportProgress(itercnt(4) / seccnt(4))
                    End If
                End If
            End If
        Loop

    End Sub

    ' This event handler 4 updates the progress.
    Private Sub backgroundWorkerpp4_ProgressChanged(ByVal sender As System.Object, _
    ByVal e As ProgressChangedEventArgs) Handles BackgroundWorkerpp4.ProgressChanged
        ResultLabelpp4.Text = (e.ProgressPercentage.ToString())
    End Sub

    ' This event handler 4 deals with the results of the background operation.
    Private Sub backgroundWorkerpp4_RunWorkerCompleted(ByVal sender As System.Object, _
    ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorkerpp4.RunWorkerCompleted
        If e.Cancelled = True Then
            ResultLabelpp4.Text = "Canceled!"
        ElseIf e.Error IsNot Nothing Then
            ResultLabelpp4.Text = "Error: " & e.Error.Message
        Else
            ResultLabelpp4.Text = "Done!"
        End If
    End Sub

    ' This event handler 5 is where the time-consuming work is done.
    Private Sub backgroundWorkerpp5_DoWork(ByVal sender As System.Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorkerpp5.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        Dim i, j, pstr As Integer
        Dim sec1, sec2 As Integer
        sec1 = Second(Now)
        pstr = 4
        Do
            itercnt(5) = itercnt(5) + 1
            If state(5) = StartSt Then
                For ip = 1 To loadd
                    For i = pstr To 10 Step np
                        For j = 0 To 10
                            x(i, j) = y(i, j) + z(i, j)
                        Next
                    Next
                Next
                state(5) = StopSt
            End If

            'If (worker.CancellationPending = True) Or state(4) = CancelSt Then
            If state(5) = CancelSt Then
                e.Cancel = True
                state(5) = Endst
                Debug.Print("pp5 Cancelst " + Str(state(5)))
                Exit Sub
            Else
                sec2 = Second(Now)
                If sec2 <> sec1 Then
                    System.Threading.Thread.Sleep(1)
                    sec1 = Second(Now)
                    seccnt(5) = seccnt(5) + 1
                    If seccnt(5) <= 0 Then
                        itercnt(5) = 0
                        worker.ReportProgress(0)
                    Else
                        worker.ReportProgress(itercnt(5) / seccnt(5))
                    End If
                End If
            End If
        Loop

    End Sub

    ' This event handler 5 updates the progress.
    Private Sub backgroundWorkerpp5_ProgressChanged(ByVal sender As System.Object, _
    ByVal e As ProgressChangedEventArgs) Handles BackgroundWorkerpp5.ProgressChanged
        ResultLabelpp5.Text = (e.ProgressPercentage.ToString())
    End Sub

    ' This event handler 5 deals with the results of the background operation.
    Private Sub backgroundWorkerpp5_RunWorkerCompleted(ByVal sender As System.Object, _
    ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorkerpp5.RunWorkerCompleted
        If e.Cancelled = True Then
            ResultLabelpp5.Text = "Canceled!"
        ElseIf e.Error IsNot Nothing Then
            ResultLabelpp5.Text = "Error: " & e.Error.Message
        Else
            ResultLabelpp5.Text = "Done!"
        End If
    End Sub

    Sub Init()

        For i = 0 To 10
            For j = 0 To 10
                y(i, j) = (i + 1) / (j + 1)
                z(i, j) = 3.14 / y(i, j)
            Next
        Next

    End Sub



    Sub InitForm()
        Dim hh, dhh As Integer
        Dim dd, ddd As Integer
        '
        'Row  1
        '
        hh = 12 : dhh = 34
        Me.StateL.Location = New System.Drawing.Point(3, hh)
        Me.StateL.Size = New System.Drawing.Size(32, 13)

        dd = 60 : ddd = 70
        Me.StateTpp1.Location = New System.Drawing.Point(dd, hh)
        Me.StateTpp1.Size = New System.Drawing.Size(64, 20)

        dd = dd + ddd
        Me.StateTpp2.Location = New System.Drawing.Point(dd, hh)
        Me.StateTpp2.Size = New System.Drawing.Size(64, 20)

        dd = dd + ddd
        Me.StateTpp3.Location = New System.Drawing.Point(dd, hh)
        Me.StateTpp3.Size = New System.Drawing.Size(64, 20)

        dd = dd + ddd
        Me.StateTpp4.Location = New System.Drawing.Point(dd, hh)
        Me.StateTpp4.Size = New System.Drawing.Size(64, 20)

        dd = dd + ddd
        Me.StateTpp5.Location = New System.Drawing.Point(dd, hh)
        Me.StateTpp5.Size = New System.Drawing.Size(64, 20)
        '
        'Row  2
        '
        hh = hh + dhh
        Me.ProcL.Location = New System.Drawing.Point(3, hh)
        Me.ProcL.Size = New System.Drawing.Size(39, 13)

        dd = 60
        Me.ProcTpp1.Location = New System.Drawing.Point(dd, hh)
        Me.ProcTpp1.Size = New System.Drawing.Size(64, 20)

        dd = dd + ddd
        Me.ProcTpp2.Location = New System.Drawing.Point(dd, hh)
        Me.ProcTpp2.Size = New System.Drawing.Size(64, 20)

        dd = dd + ddd
        Me.ProcTpp3.Location = New System.Drawing.Point(dd, hh)
        Me.ProcTpp3.Size = New System.Drawing.Size(64, 20)

        dd = dd + ddd
        Me.ProcTpp4.Location = New System.Drawing.Point(dd, hh)
        Me.ProcTpp4.Size = New System.Drawing.Size(64, 20)

        dd = dd + ddd
        Me.ProcTpp5.Location = New System.Drawing.Point(dd, hh)
        Me.ProcTpp5.Size = New System.Drawing.Size(64, 20)
        '
        'Row 3
        '
        hh = hh + dhh
        Me.Label2.Location = New System.Drawing.Point(3, hh)
        Me.Label2.Size = New System.Drawing.Size(67, 13)

        dd = 85
        Me.ResultLabelpp1.Location = New System.Drawing.Point(dd, hh)
        Me.ResultLabelpp1.Size = New System.Drawing.Size(70, 13)

        dd = dd + ddd
        Me.ResultLabelpp2.Location = New System.Drawing.Point(dd, hh)
        Me.ResultLabelpp2.Size = New System.Drawing.Size(70, 13)

        dd = dd + ddd
        Me.ResultLabelpp3.Location = New System.Drawing.Point(dd, hh)
        Me.ResultLabelpp3.Size = New System.Drawing.Size(70, 13)

        dd = dd + ddd
        Me.ResultLabelpp4.Location = New System.Drawing.Point(dd, hh)
        Me.ResultLabelpp4.Size = New System.Drawing.Size(70, 13)

        dd = dd + ddd
        Me.ResultLabelpp5.Location = New System.Drawing.Point(dd, hh)
        Me.ResultLabelpp5.Size = New System.Drawing.Size(70, 13)
        '
        'Row  4
        '
        dd = 80 : ddd = 90
        hh = hh + dhh
        Me.nProcL.Location = New System.Drawing.Point(dd - 40, hh)
        Me.nProcL.Size = New System.Drawing.Size(55, 13)

        Me.NProcT.Location = New System.Drawing.Point(dd, hh)
        Me.NProcT.Size = New System.Drawing.Size(40, 20)

        dd = dd + ddd
        Me.LoadL.Location = New System.Drawing.Point(dd - 40, hh)
        Me.LoadL.Size = New System.Drawing.Size(55, 13)

        Me.loadT.Location = New System.Drawing.Point(dd, hh)
        Me.loadT.Size = New System.Drawing.Size(40, 20)

        dd = dd + ddd
        Me.seccntL.Location = New System.Drawing.Point(dd - 40, hh)
        Me.seccntL.Size = New System.Drawing.Size(55, 13)

        Me.seccntT.Location = New System.Drawing.Point(dd, hh)
        Me.seccntT.Size = New System.Drawing.Size(40, 20)

        '
        ' row 5 startAsyncButton   cancelAsyncButton  endAsyncButton   MonitorButton
        '
        dd = 60
        hh = hh + dhh
        Me.StartAsyncButton.Location = New System.Drawing.Point(dd, hh)
        Me.StartAsyncButton.Size = New System.Drawing.Size(63, 25)

        dd = dd + ddd
        Me.CancelAsyncButton.Location = New System.Drawing.Point(dd, hh)
        Me.CancelAsyncButton.Size = New System.Drawing.Size(63, 25)

        dd = dd + ddd
        Me.EndAsyncButton.Location = New System.Drawing.Point(dd, hh)
        Me.EndAsyncButton.Size = New System.Drawing.Size(63, 25)

        dd = dd + ddd
        Me.MonitorButton.Location = New System.Drawing.Point(dd, hh)
        Me.MonitorButton.Size = New System.Drawing.Size(63, 25)

        ' Form1
        dd = dd + ddd : hh = hh + dhh
        Me.ClientSize = New System.Drawing.Size(dd - 10, hh)

    End Sub


End Class