G
GCeaser
I am encountering a challenge while using WaitAny to detect when any
of my async processes have finished.
The scenario is I have a master class which instantiates two other
classes and calls a method on each asynchronously. The async method
returns output that is processed via code on the main thread.
So, I have been trying to use the WaitAny passing it an array of the
WaitHandles. I have this code in a loop that checks to see if we are
done with all async processes. The problem with this approach is that
after the first async process comes back, and I go back through the
loop to wait for the next async process to finish (using WaitAny
again) - the same async process complete re-fires the same async item
I just processed.
If have also tried to use the AutoResetEvent in the WaitAny event --
But I can figure out how to have the methods being executed
asynchronously in my class object to call the Set method on the
AutoResetEvent to trigger my main thread to continue.
I have also looked at the internet for some good examples of what I
am trying to do and have been unable to find any -- at least none if
VB code (and I am not too familiar with more complex C# syntax that
would be used in this type of an example.) If anyone has a good VB
sample that I can refer to, that would be much appreciated. It not,
the code is below. This code us currently NOT set to use the
AutoResetEvent for the reason stated above.
Any assistance would be greatly appreciated!!!
Option Strict On
Option Explicit On
Imports GATSDataSourcesDAL
Imports System.Threading
Public Class AsynTestClass
Private iobj_GATSDataSource As GATSDAL = Nothing
Private iobj_GTISDataSource As GTISDAL = Nothing
'Delegate declarations
Private Delegate Function ReturnGATSDataSet_Delegate() As DataSet
Private Delegate Function ReturnGTISDataSet_Delegate() As DataSet
'Variables to create the delegates
Private iobj_ReturnGATSDataSet_Delegate As
ReturnGATSDataSet_Delegate
Private iobj_ReturnGTISDataSet_Delegate As
ReturnGTISDataSet_Delegate
'Declare the results
Private iobj_ReturnGATSDataSet_AsyncResults As IAsyncResult
Private iobj_ReturnGTISDataSet_AsyncResults As IAsyncResult
Private li_NumberOfDataSources As Integer = 2
'Declare the WaitHandles Array
Private ia_WaitHandles(li_NumberOfDataSources - 1) As WaitHandle
'Documentation says threading items should be called from a Multi-
Threaded Appt
<MTAThread()> _
Public Function ReturnDataSet2() As Dictionary(Of String, DataSet)
'This will return an array of dataset
Dim ls_ReturnDataSet As DataSet = Nothing
Dim lb_Done As Boolean = False
Dim li_DoneCount As Integer
Dim li_IX As Integer = -1
Dim la_AsyncResults(li_NumberOfDataSources - 1) As
IAsyncResult
Dim ls_DataSourceName As String
Dim lobj_ReturnDictionary As Dictionary(Of String, DataSet) =
New Dictionary(Of String, DataSet)
'Create the Data Access Layer
iobj_GATSDataSource = New GATSDAL
'Create and call the first asyn method
iobj_ReturnGATSDataSet_Delegate = New
ReturnGATSDataSet_Delegate(AddressOf
iobj_GATSDataSource.ReturnDataSet)
'Call Async to local DLL to get the data
iobj_ReturnGATSDataSet_AsyncResults =
iobj_ReturnGATSDataSet_Delegate.BeginInvoke(Nothing, "GATS")
'Add the async results and waithandles to the array
li_IX += 1
la_AsyncResults(li_IX) = iobj_ReturnGATSDataSet_AsyncResults
ia_WaitHandles(li_IX) =
iobj_ReturnGATSDataSet_AsyncResults.AsyncWaitHandle
'Create and call the first asyn method
iobj_GTISDataSource = New GTISDAL
'Create the proxy class to call the Data Access Layer
iobj_ReturnGTISDataSet_Delegate = New
ReturnGTISDataSet_Delegate(AddressOf
iobj_GTISDataSource.ReturnDataSet)
'Call Async to local DLL to get the data
iobj_ReturnGTISDataSet_AsyncResults =
iobj_ReturnGTISDataSet_Delegate.BeginInvoke(Nothing, "GTIS")
'Add the async results and waithandles to the array
li_IX += 1
la_AsyncResults(li_IX) = iobj_ReturnGATSDataSet_AsyncResults
ia_WaitHandles(1) =
iobj_ReturnGTISDataSet_AsyncResults.AsyncWaitHandle
'Wait till all the results are back of the transaction times
out
Do Until lb_Done = True
li_IX = WaitHandle.WaitAny(ia_WaitHandles,
TimeSpan.FromSeconds(15), False)
'Get the correct asyncresults - Use the state to know the
object type
ls_DataSourceName =
la_AsyncResults(li_IX).AsyncState.ToString
Select Case ls_DataSourceName
Case "GATS"
'This will get the dataset and raise any errors
lobj_ReturnDictionary.Add(ls_DataSourceName,
iobj_ReturnGATSDataSet_Delegate.EndInvoke(la_AsyncResults(li_IX)))
Case "GTIS"
'This will get the dataset and raise any errors
lobj_ReturnDictionary.Add(ls_DataSourceName,
iobj_ReturnGTISDataSet_Delegate.EndInvoke(la_AsyncResults(li_IX)))
End Select
'Decide if we should end the loop
li_DoneCount += 1
If li_DoneCount > ia_WaitHandles.GetUpperBound(0) Then
lb_Done = True
End If
Loop
Return lobj_ReturnDictionary
End Function
End Class
of my async processes have finished.
The scenario is I have a master class which instantiates two other
classes and calls a method on each asynchronously. The async method
returns output that is processed via code on the main thread.
So, I have been trying to use the WaitAny passing it an array of the
WaitHandles. I have this code in a loop that checks to see if we are
done with all async processes. The problem with this approach is that
after the first async process comes back, and I go back through the
loop to wait for the next async process to finish (using WaitAny
again) - the same async process complete re-fires the same async item
I just processed.
If have also tried to use the AutoResetEvent in the WaitAny event --
But I can figure out how to have the methods being executed
asynchronously in my class object to call the Set method on the
AutoResetEvent to trigger my main thread to continue.
I have also looked at the internet for some good examples of what I
am trying to do and have been unable to find any -- at least none if
VB code (and I am not too familiar with more complex C# syntax that
would be used in this type of an example.) If anyone has a good VB
sample that I can refer to, that would be much appreciated. It not,
the code is below. This code us currently NOT set to use the
AutoResetEvent for the reason stated above.
Any assistance would be greatly appreciated!!!
Option Strict On
Option Explicit On
Imports GATSDataSourcesDAL
Imports System.Threading
Public Class AsynTestClass
Private iobj_GATSDataSource As GATSDAL = Nothing
Private iobj_GTISDataSource As GTISDAL = Nothing
'Delegate declarations
Private Delegate Function ReturnGATSDataSet_Delegate() As DataSet
Private Delegate Function ReturnGTISDataSet_Delegate() As DataSet
'Variables to create the delegates
Private iobj_ReturnGATSDataSet_Delegate As
ReturnGATSDataSet_Delegate
Private iobj_ReturnGTISDataSet_Delegate As
ReturnGTISDataSet_Delegate
'Declare the results
Private iobj_ReturnGATSDataSet_AsyncResults As IAsyncResult
Private iobj_ReturnGTISDataSet_AsyncResults As IAsyncResult
Private li_NumberOfDataSources As Integer = 2
'Declare the WaitHandles Array
Private ia_WaitHandles(li_NumberOfDataSources - 1) As WaitHandle
'Documentation says threading items should be called from a Multi-
Threaded Appt
<MTAThread()> _
Public Function ReturnDataSet2() As Dictionary(Of String, DataSet)
'This will return an array of dataset
Dim ls_ReturnDataSet As DataSet = Nothing
Dim lb_Done As Boolean = False
Dim li_DoneCount As Integer
Dim li_IX As Integer = -1
Dim la_AsyncResults(li_NumberOfDataSources - 1) As
IAsyncResult
Dim ls_DataSourceName As String
Dim lobj_ReturnDictionary As Dictionary(Of String, DataSet) =
New Dictionary(Of String, DataSet)
'Create the Data Access Layer
iobj_GATSDataSource = New GATSDAL
'Create and call the first asyn method
iobj_ReturnGATSDataSet_Delegate = New
ReturnGATSDataSet_Delegate(AddressOf
iobj_GATSDataSource.ReturnDataSet)
'Call Async to local DLL to get the data
iobj_ReturnGATSDataSet_AsyncResults =
iobj_ReturnGATSDataSet_Delegate.BeginInvoke(Nothing, "GATS")
'Add the async results and waithandles to the array
li_IX += 1
la_AsyncResults(li_IX) = iobj_ReturnGATSDataSet_AsyncResults
ia_WaitHandles(li_IX) =
iobj_ReturnGATSDataSet_AsyncResults.AsyncWaitHandle
'Create and call the first asyn method
iobj_GTISDataSource = New GTISDAL
'Create the proxy class to call the Data Access Layer
iobj_ReturnGTISDataSet_Delegate = New
ReturnGTISDataSet_Delegate(AddressOf
iobj_GTISDataSource.ReturnDataSet)
'Call Async to local DLL to get the data
iobj_ReturnGTISDataSet_AsyncResults =
iobj_ReturnGTISDataSet_Delegate.BeginInvoke(Nothing, "GTIS")
'Add the async results and waithandles to the array
li_IX += 1
la_AsyncResults(li_IX) = iobj_ReturnGATSDataSet_AsyncResults
ia_WaitHandles(1) =
iobj_ReturnGTISDataSet_AsyncResults.AsyncWaitHandle
'Wait till all the results are back of the transaction times
out
Do Until lb_Done = True
li_IX = WaitHandle.WaitAny(ia_WaitHandles,
TimeSpan.FromSeconds(15), False)
'Get the correct asyncresults - Use the state to know the
object type
ls_DataSourceName =
la_AsyncResults(li_IX).AsyncState.ToString
Select Case ls_DataSourceName
Case "GATS"
'This will get the dataset and raise any errors
lobj_ReturnDictionary.Add(ls_DataSourceName,
iobj_ReturnGATSDataSet_Delegate.EndInvoke(la_AsyncResults(li_IX)))
Case "GTIS"
'This will get the dataset and raise any errors
lobj_ReturnDictionary.Add(ls_DataSourceName,
iobj_ReturnGTISDataSet_Delegate.EndInvoke(la_AsyncResults(li_IX)))
End Select
'Decide if we should end the loop
li_DoneCount += 1
If li_DoneCount > ia_WaitHandles.GetUpperBound(0) Then
lb_Done = True
End If
Loop
Return lobj_ReturnDictionary
End Function
End Class