Imports System.ComponentModel
Imports System.Drawing

Public Class VStest2Form

    ' 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), tperf(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)))
                tperf(1) = 0
                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
                        tperf(1) = 0
                        worker.ReportProgress(0)
                    Else
                        tperf(1) = itercnt(1) / seccnt(1)
                        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))
        TPerfT.Text = Str(tperf(1) + tperf(2) + tperf(3) + tperf(4) + tperf(5))
    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
            If state(2) = StartSt Then
                itercnt(2) = itercnt(2) + 1
                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)))
                tperf(2) = 0
                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
                        tperf(2) = 0
                        worker.ReportProgress(0)
                    Else
                        tperf(2) = itercnt(2) / seccnt(2)
                        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
            If state(3) = StartSt Then
                itercnt(3) = itercnt(3) + 1
                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)))
                tperf(3) = 0
                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
                        tperf(3) = 0
                        worker.ReportProgress(0)
                    Else
                        tperf(3) = itercnt(3) / seccnt(3)
                        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
            If state(4) = StartSt Then
                itercnt(4) = itercnt(4) + 1
                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)))
                tperf(4) = 0
                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
                        tperf(4) = 0
                        worker.ReportProgress(0)
                    Else
                        tperf(4) = itercnt(4) / seccnt(4)
                        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
            If state(5) = StartSt Then
                itercnt(5) = itercnt(5) + 1
                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)))
                tperf(5) = 0
                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
                        tperf(5) = 0
                        worker.ReportProgress(0)
                    Else
                        tperf(5) = itercnt(5) / seccnt(5)
                        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)

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

        Me.TPerfT.Location = New System.Drawing.Point(dd, hh)
        Me.TPerfT.Size = New System.Drawing.Size(55, 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