Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Drawing
Imports System.Threading
Imports System.Windows.Forms
Public Class FibonacciPPForm
Inherits System.Windows.Forms.Form
Private numberToCompute As Integer = 0
Private numberToCompute1 As Integer = 0
Private highestPercentageReached As Integer = 0
Public cancelreq As Integer
Const npmax = 5
Public nnin(npmax) As Integer
Public nnout(npmax) As Long
Public state(npmax), np, nfact As Integer
Public Const StartSt As Integer = 1, ActiveSt As Integer = 2, StopSt As Integer = 0, CancelSt As Integer = 3, Endst = 0
Public Const Trace = 1
Public Sub New()
InitializeComponent()
InitializeForm()
Init()
End Sub 'New
Private Sub StartAsyncButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles StartAsyncButton.Click
If Trace = 1 Then Debug.Print("StartAsyncButton")
' Reset the text in the result label.
Me.progressBar1.Value = 0
resultLabel1.Text = [String].Empty
resultLabel2.Text = [String].Empty
cancelreq = 0
' Disable the UpDown control until
' the asynchronous operation is done.
Me.numericUpDown1.Enabled = False
' Reset the variable for percentage tracking.
highestPercentageReached = 0
StartAsyncButton.Visible = False
CancelAsyncButton.Text = "Cancel Async"
Master()
CancelAsyncButton.Text = "End Async"
End Sub
Sub Master()
Dim Duration, time1, time2 As Long
Dim val1 As Long
Dim npreq, cyc, cnt As Single
npreq = 0
' Get the value from the UpDown control.
numberToCompute = CInt(numericUpDown1.Value)
If numberToCompute < 9 Then
numberToCompute = 9
numericUpDown1.Value = 9
End If
npreq = CInt(numericUpDown2.Value) ' request n
If npreq > numberToCompute Then
npreq = numberToCompute
numericUpDown2.Value = npreq
End If
cyc = CInt(numericUpDown3.Value)
Debug.Print("Main1 npreq " + Str(npreq) + " np " + Str(np) + " numberToCompute " + Str(numberToCompute) + " cyc" + Str(cnt))
If npreq <> np Then
Assign(npreq)
End If
time1 = Hour(Now) * 3600 + Minute(Now) * 60 + Second(Now)
nnin(1) = numberToCompute - 4 ' * 1
nnin(2) = numberToCompute - 5 ' * 4
nnin(3) = numberToCompute - 6 ' * 6
nnin(4) = numberToCompute - 7 ' * 4
nnin(5) = numberToCompute - 8 ' * 1
nfact = 5
cnt = 0
Do
Me.resultLabel3.Text = cnt
cnt = cnt + 1
If np > 1 Then
For j = 2 To np
state(j) = StartSt
Next
End If
' Compute Fibonacci numbers pp=1
Select Case np
Case Is = 1
nnout(1) = ComputeFibonacci(nnin(1))
nnout(2) = ComputeFibonacci(nnin(2))
nnout(3) = ComputeFibonacci(nnin(3))
nnout(4) = ComputeFibonacci(nnin(4))
nnout(5) = ComputeFibonacci(nnin(5))
Case Is = 2
nnout(1) = ComputeFibonacci(nnin(1))
nnout(4) = ComputeFibonacci(nnin(4))
nnout(5) = ComputeFibonacci(nnin(5))
Case Else
nnout(1) = ComputeFibonacci(nnin(1))
End Select
If np > 1 Then
Do
Application.DoEvents()
Loop Until state(2) = StopSt And state(3) = StopSt And state(4) = StopSt And state(5) = StopSt
End If
If cancelreq = 0 Then progressBar1.Value = cnt * 100 / cyc
val1 = nnout(1) + 4 * nnout(2) + 6 * nnout(3) + 4 * nnout(4) + nnout(5)
time2 = Hour(Now) * 3600 + Minute(Now) * 60 + Second(Now)
Duration = time2 - time1
If cancelreq = 0 Then
resultLabel1.Text = val1
resultLabel2.Text = Duration / cnt
resultLabel3.Text = cnt
ElseIf cnt = 1 Then
resultLabel1.Text = "Cancelled"
resultLabel2.Text = "Cancelled"
End If
Loop Until cnt = cyc Or cancelreq = 1
If Trace = 1 Then
Dim a As String
a = "Main1 "
For i = 1 To nfact Step 1
a = a + " " + Str(i) + " " + Str(nnout(i))
Next
Debug.Print(a)
Debug.Print("Main1 " + " val1 " + Str(val1) + " Duration " + Str(Duration) + " " + Str(Duration / cnt))
End If
StartAsyncButton.Visible = Visible
Me.numericUpDown1.Enabled = True
If cancelreq = 1 Then np = 1
End Sub
Function ComputeFibonacci(ByVal n As Integer) As Long
' The parameter n must be >= 0 and <= 91.
' Fib(n), with n > 91, overflows a long.
Dim result As Long = 0
If n < 0 OrElse n > 91 Then
Throw New ArgumentException("value must be >= 0 and <= 91", "n")
End If
If n > 25 Then Application.DoEvents()
' Debug.Print("ComputeFibonacci" + Str(n))
If cancelreq = 0 Then
If n < 2 Then
If n = 0 Then result = 0 Else result = 1
Else
result = ComputeFibonacci(n - 1) + ComputeFibonacci(n - 2)
End If
Else
' Report progress as a percentage of the total task.
' Dim percentComplete As Integer = _
' CSng(n) / CSng(nnin(1)) * 100 * (cnt / cyc)
' Debug.Print(Str(n) + " " + Str(percentComplete))
' worker.ReportProgress(percentComplete)
' If percentComplete > highestPercentageReached Then
' highestPercentageReached = percentComplete
' progressBar1.Value = highestPercentageReached
' End If
End If
Return result
End Function
Private Sub CancelAsyncButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles CancelAsyncButton.Click
If CancelAsyncButton.Text = "Cancel Async" Then
cancelreq = 1
' Enable the End button.
numericUpDown1.Enabled = True
CancelAsyncButton.Text = "End Async"
Else
End
End If
End Sub 'CancelAsyncButton
' This event handler is where the actual work is done.
Private Sub backgroundWorker1_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles backgroundWorker1.DoWork
' Get the BackgroundWorker object that raised this event.
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
Const pp As Single = 2
Do
If state(pp) = StartSt Then
state(pp) = ActiveSt
' Compute Fibonacci numbers pp=2
Select Case np
Case Is = 2
nnout(2) = ComputeFibonacci(nnin(2))
nnout(3) = ComputeFibonacci(nnin(3))
Case Is = 3
nnout(2) = ComputeFibonacci(nnin(2))
nnout(5) = ComputeFibonacci(nnin(5))
Case Is = 4, 5
nnout(2) = ComputeFibonacci(nnin(2))
End Select
state(pp) = StopSt
Else
System.Threading.Thread.Sleep(1)
End If
Loop Until cancelreq = 1 Or state(pp) = CancelSt
state(pp) = Endst
End Sub 'backgroundWorker1_DoWork
' This event handler is where the actual work is done.
Private Sub backgroundWorker2_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles backgroundWorker2.DoWork
' Get the BackgroundWorker object that raised this event.
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
Const pp As Single = 3
Do
If state(pp) = StartSt Then
state(pp) = ActiveSt
' Compute Fibonacci numbers pp=3
Select Case np
Case Is = 3
nnout(3) = ComputeFibonacci(nnin(3))
nnout(4) = ComputeFibonacci(nnin(4))
Case Is = 4, 5
nnout(3) = ComputeFibonacci(nnin(3))
End Select
state(pp) = StopSt
Else
System.Threading.Thread.Sleep(1)
End If
Loop Until cancelreq = 1 Or state(pp) = CancelSt
state(pp) = Endst
End Sub 'backgroundWorker2_DoWork
' This event handler is where the actual work is done.
Private Sub backgroundWorker3_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles backgroundWorker3.DoWork
' Get the BackgroundWorker object that raised this event.
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
Const pp As Single = 4
Do
If state(pp) = StartSt Then
state(pp) = ActiveSt
' Compute Fibonacci numbers pp=4
Select Case np
Case Is = 4
nnout(4) = ComputeFibonacci(nnin(4))
nnout(5) = ComputeFibonacci(nnin(5))
Case Is = 5
nnout(4) = ComputeFibonacci(nnin(4))
End Select
state(pp) = StopSt
Else
System.Threading.Thread.Sleep(1)
End If
Loop Until cancelreq = 1 Or state(pp) = CancelSt
state(pp) = Endst
End Sub 'backgroundWorker3_DoWork
' This event handler is where the actual work is done.
Private Sub backgroundWorker4_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker4.DoWork
' Get the BackgroundWorker object that raised this event.
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
Const pp As Single = 5
Do
If state(pp) = StartSt Then
state(pp) = ActiveSt
' Compute Fibonacci numbers pp=5
Select Case np
Case Is = 5
nnout(5) = ComputeFibonacci(nnin(5))
End Select
state(pp) = StopSt
Else
System.Threading.Thread.Sleep(1)
End If
Loop Until cancelreq = 1 Or state(pp) = CancelSt
state(pp) = Endst
End Sub 'backgroundWorker4_DoWork
Private Sub Init()
np = 0 'Number of processors
For i = 1 To npmax : nnout(i) = 0 : Next i
If Trace = 1 Then Debug.Print("Init Trace = " + Str(Trace))
End Sub
Private Sub Assign(ByVal npreq)
' npreq = np request np = actual
For i = 1 To npmax
If npreq >= i And np < i Then
Select Case i
Case Is = 1
If Trace = 1 Then Debug.Print("Assign " + Str(i))
Case Is = 2
backgroundWorker1.RunWorkerAsync(i)
If Trace = 1 Then Debug.Print("Assign " + Str(i))
Case Is = 3
backgroundWorker2.RunWorkerAsync(i)
If Trace = 1 Then Debug.Print("Assign " + Str(i))
Case Is = 4
backgroundWorker3.RunWorkerAsync(i)
If Trace = 1 Then Debug.Print("Assign " + Str(i))
Case Is = 5
BackgroundWorker4.RunWorkerAsync(i)
If Trace = 1 Then Debug.Print("Assign " + Str(i))
End Select
End If
If npreq < i And np >= i Then
Select Case i
Case Is = 1
If Trace = 1 Then Debug.Print("Cancel " + Str(i))
Case Is = 2
state(i) = CancelSt
If Trace = 1 Then Debug.Print("Cancel " + Str(i))
Case Is = 3
state(i) = CancelSt
If Trace = 1 Then Debug.Print("Cancel " + Str(i))
Case Is = 4
state(i) = CancelSt
If Trace = 1 Then Debug.Print("Cancel " + Str(i))
Case Is = 5
state(i) = CancelSt
If Trace = 1 Then Debug.Print("Cancel " + Str(i))
End Select
End If
Next i
np = npreq
End Sub
Private Sub InitializeForm()
Dim dd, hh As Single
'
'numericUpDown1
'
dd = 16 : hh = 16
Me.numericUpDown1.Location = New System.Drawing.Point(dd, hh)
'
'resultLabel1
'
Me.resultLabel1.Location = New System.Drawing.Point(112, hh)
Me.resultLabel1.Size = New System.Drawing.Size(70, 20)
Me.resultLabel2.Location = New System.Drawing.Point(200, hh)
Me.resultLabel2.Size = New System.Drawing.Size(70, 20)
'
'progressBar1
'
hh = 48
Me.progressBar1.Location = New System.Drawing.Point(18, hh)
Me.progressBar1.Size = New System.Drawing.Size(256, 8)
hh = hh + 24
dd = 10
Me.Label1.Location = New System.Drawing.Point(dd, hh)
Me.Label1.Size = New System.Drawing.Size(30, 20)
dd = dd + 30 + 10
Me.numericUpDown2.Location = New System.Drawing.Point(dd, hh)
Me.numericUpDown2.Size = New System.Drawing.Size(40, 20)
Me.numericUpDown2.Maximum = New Decimal(New Integer() {npmax, 0, 0, 0})
dd = dd + 40 + 10
Me.Label2.Location = New System.Drawing.Point(dd, hh)
Me.Label2.Size = New System.Drawing.Size(33, 20)
dd = dd + 33 + 10
Me.numericUpDown3.Location = New System.Drawing.Point(dd, hh)
Me.numericUpDown3.Size = New System.Drawing.Size(40, 20)
dd = dd + 40 + 15
Me.resultLabel3.Location = New System.Drawing.Point(dd, hh)
'
'startAsyncButton
'
hh = hh + 30
dd = 16
Me.StartAsyncButton.Location = New System.Drawing.Point(dd, hh)
Me.StartAsyncButton.Size = New System.Drawing.Size(80, 20)
'
'CancelAsyncButton
'
dd = dd + 80 + 10
Me.CancelAsyncButton.Location = New System.Drawing.Point(dd, hh)
Me.CancelAsyncButton.Size = New System.Drawing.Size(80, 20)
'
'FibonacciForm
'
Me.ClientSize = New System.Drawing.Size(292, hh + 30)
End Sub 'InitializeComponent
_
Shared Sub Main()
Application.Run(New FibonacciPPForm)
End Sub 'Main
End Class 'FibonacciPPForm