A
Anthony Lopez
I attempted to test how waithandles and autoresetevents work with one
another in hopes to be able to use them in my application. However, I keep
hitting the wall.
Can some one look over the attached code and tell me what I am doing wrong.
I am getting the following errors:
C:\Development\Net\VB\TestThread\TestThread\bin>testthread
Waiting for all current task to complete
Task Id = 1 Sequence = 1
Task Run Id = 10 Task Mode = True
Task Id = 2 Sequence = 1
Task Run Id = 10 Task Mode = True
Task Id = 3 Sequence = 1
Task Run Id = 10 Task Mode = True
Unhandled Exception: System.NullReferenceException: Object reference not set
to
an instance of an object.
at System.Threading.WaitHandle.WaitMultiple(WaitHandle[] waitHandles,
Int32 m
illisecondsTimeout, Boolean exitContext, Boolean WaitAll)
at System.Threading.WaitHandle.WaitAll(WaitHandle[] waitHandles, Int32
millis
econdsTimeout, Boolean exitContext)
at System.Threading.WaitHandle.WaitAll(WaitHandle[] waitHandles)
at TestThread.TestThread.Main() in
C:\Development\Net\VB\TestThread\TestThrea
d\Module1.vb:line 48
What's odd about this is that I closely follows the example in Microsoft's
MSDN web site.
' File: TestThread.vb
Option Strict On
Option Explicit On
Imports System
Imports System.Console
Imports System.io
Imports System.Threading
Imports System.Threading.Thread
Module TestThread
Const MAXTASK As Integer = 5
Const MAXTHREAD As Integer = 25
<MTAThreadAttribute()> _
Sub Main()
Dim Tasks As New ArrayList
Dim RunTask As CTask
Dim iRunTaskId As Integer = 10
Dim bRunTaskMode As Boolean = True
Dim Sync(3) As AutoResetEvent
'Create an array used to define the task's Id and Sequence
Dim TaskDefn(,) As Integer = New Integer(,) {{1, 1}, {2, 1}, {3, 1},
{4, 2}, {5, 3}}
' Create all the task using the TaskDefn array
For i As Integer = 0 To MAXTASK - 1
Dim theTask As CTask = New CTask
theTask.Id = TaskDefn(i, 0)
theTask.Sequence = TaskDefn(i, 1)
Tasks.Add(theTask)
Next i
Dim iSeq As Integer = 1000
Dim iTask As Integer = 0
For Each RunTask In Tasks
If iSeq < RunTask.Sequence Then
Console.WriteLine("Waiting for all current task to
complete")
WaitHandle.WaitAll(Sync) ' <<< THIS IS THE ERROR LINE
Console.WriteLine("All task have completed")
iTask = 0
End If
iSeq = RunTask.Sequence
Sync(iTask) = New AutoResetEvent(False)
Dim TaskParam As New CTaskParam(RunTask, bRunTaskMode,
iRunTaskId, Sync(iTask))
Try
ThreadPool.QueueUserWorkItem(AddressOf cbStartProgram,
TaskParam)
Catch ex As Exception
Console.WriteLine("Main Error Message: " + vbCrLf +
ex.Message)
End Try
iTask += iTask
Next
Sleep(3000)
End Sub
Class CTaskParam
Public Task As CTask
Public Mode As Boolean
Public RunId As Integer
Public SignalWhenDone As AutoResetEvent
Sub New(ByVal TaskParam As CTask, ByVal ModeParam As Boolean, ByVal
RunIdParam As Integer, ByVal SignalParam As AutoResetEvent)
Me.Task = TaskParam
Me.Mode = ModeParam
Me.RunId = RunIdParam
Me.SignalWhenDone = SignalParam
End Sub
End Class
' This module represent an intermediary module used to create a thread
and process
' the parameters, eventually invokeing the actual object/module
Sub cbStartProgram(ByVal theTaskParam As Object)
' Get the arguments
Dim TaskParam As CTaskParam = CType(theTaskParam, CTaskParam)
Try
' Invoke the object
TaskParam.Task.Run(TaskParam.RunId, TaskParam.Mode)
Catch ex As Exception
Console.WriteLine("Start Program - Error Message: " + vbCrLf +
ex.Message)
Finally
TaskParam.SignalWhenDone.Set()
End Try
End Sub
End Module
' This Class represents any task that can be call from .Net
'
Class CTask
Dim iSequence As Integer
Dim iId As Integer
Property Sequence() As Integer
Get
Return iSequence
End Get
Set(ByVal Value As Integer)
iSequence = Value
End Set
End Property
Property Id() As Integer
Get
Return iId
End Get
Set(ByVal Value As Integer)
iId = Value
End Set
End Property
Sub Run(ByVal iTaskRunId As Int32, ByVal bTaskMode As Boolean)
Console.WriteLine("Task Id = " + Id.ToString + " Sequence = " +
Sequence.ToString)
Console.WriteLine("Task Run Id = " + iTaskRunId.ToString + " Task
Mode = " + bTaskMode.ToString)
Console.WriteLine()
Return
End Sub
End Class
another in hopes to be able to use them in my application. However, I keep
hitting the wall.
Can some one look over the attached code and tell me what I am doing wrong.
I am getting the following errors:
C:\Development\Net\VB\TestThread\TestThread\bin>testthread
Waiting for all current task to complete
Task Id = 1 Sequence = 1
Task Run Id = 10 Task Mode = True
Task Id = 2 Sequence = 1
Task Run Id = 10 Task Mode = True
Task Id = 3 Sequence = 1
Task Run Id = 10 Task Mode = True
Unhandled Exception: System.NullReferenceException: Object reference not set
to
an instance of an object.
at System.Threading.WaitHandle.WaitMultiple(WaitHandle[] waitHandles,
Int32 m
illisecondsTimeout, Boolean exitContext, Boolean WaitAll)
at System.Threading.WaitHandle.WaitAll(WaitHandle[] waitHandles, Int32
millis
econdsTimeout, Boolean exitContext)
at System.Threading.WaitHandle.WaitAll(WaitHandle[] waitHandles)
at TestThread.TestThread.Main() in
C:\Development\Net\VB\TestThread\TestThrea
d\Module1.vb:line 48
What's odd about this is that I closely follows the example in Microsoft's
MSDN web site.
' File: TestThread.vb
Option Strict On
Option Explicit On
Imports System
Imports System.Console
Imports System.io
Imports System.Threading
Imports System.Threading.Thread
Module TestThread
Const MAXTASK As Integer = 5
Const MAXTHREAD As Integer = 25
<MTAThreadAttribute()> _
Sub Main()
Dim Tasks As New ArrayList
Dim RunTask As CTask
Dim iRunTaskId As Integer = 10
Dim bRunTaskMode As Boolean = True
Dim Sync(3) As AutoResetEvent
'Create an array used to define the task's Id and Sequence
Dim TaskDefn(,) As Integer = New Integer(,) {{1, 1}, {2, 1}, {3, 1},
{4, 2}, {5, 3}}
' Create all the task using the TaskDefn array
For i As Integer = 0 To MAXTASK - 1
Dim theTask As CTask = New CTask
theTask.Id = TaskDefn(i, 0)
theTask.Sequence = TaskDefn(i, 1)
Tasks.Add(theTask)
Next i
Dim iSeq As Integer = 1000
Dim iTask As Integer = 0
For Each RunTask In Tasks
If iSeq < RunTask.Sequence Then
Console.WriteLine("Waiting for all current task to
complete")
WaitHandle.WaitAll(Sync) ' <<< THIS IS THE ERROR LINE
Console.WriteLine("All task have completed")
iTask = 0
End If
iSeq = RunTask.Sequence
Sync(iTask) = New AutoResetEvent(False)
Dim TaskParam As New CTaskParam(RunTask, bRunTaskMode,
iRunTaskId, Sync(iTask))
Try
ThreadPool.QueueUserWorkItem(AddressOf cbStartProgram,
TaskParam)
Catch ex As Exception
Console.WriteLine("Main Error Message: " + vbCrLf +
ex.Message)
End Try
iTask += iTask
Next
Sleep(3000)
End Sub
Class CTaskParam
Public Task As CTask
Public Mode As Boolean
Public RunId As Integer
Public SignalWhenDone As AutoResetEvent
Sub New(ByVal TaskParam As CTask, ByVal ModeParam As Boolean, ByVal
RunIdParam As Integer, ByVal SignalParam As AutoResetEvent)
Me.Task = TaskParam
Me.Mode = ModeParam
Me.RunId = RunIdParam
Me.SignalWhenDone = SignalParam
End Sub
End Class
' This module represent an intermediary module used to create a thread
and process
' the parameters, eventually invokeing the actual object/module
Sub cbStartProgram(ByVal theTaskParam As Object)
' Get the arguments
Dim TaskParam As CTaskParam = CType(theTaskParam, CTaskParam)
Try
' Invoke the object
TaskParam.Task.Run(TaskParam.RunId, TaskParam.Mode)
Catch ex As Exception
Console.WriteLine("Start Program - Error Message: " + vbCrLf +
ex.Message)
Finally
TaskParam.SignalWhenDone.Set()
End Try
End Sub
End Module
' This Class represents any task that can be call from .Net
'
Class CTask
Dim iSequence As Integer
Dim iId As Integer
Property Sequence() As Integer
Get
Return iSequence
End Get
Set(ByVal Value As Integer)
iSequence = Value
End Set
End Property
Property Id() As Integer
Get
Return iId
End Get
Set(ByVal Value As Integer)
iId = Value
End Set
End Property
Sub Run(ByVal iTaskRunId As Int32, ByVal bTaskMode As Boolean)
Console.WriteLine("Task Id = " + Id.ToString + " Sequence = " +
Sequence.ToString)
Console.WriteLine("Task Run Id = " + iTaskRunId.ToString + " Task
Mode = " + bTaskMode.ToString)
Console.WriteLine()
Return
End Sub
End Class