S
Sam Loveridge
Hi all. I'm relatively new to delegates and asynchronous threading and am
running into an issue. I need to asynchronously call a method (which I'm
doing with a delegate and BeginInvoke) and from the callback method, or at
some point after the EndInvoke has been called to end the asynchronous
operation I need to asynchronously call a different method.
I really want to keep this event based and use delegates and callbacks
rather than loop until completed, as there will be many instances of this
process running at the same time in parallel and I don't want to strain
resources.
The results are that the first method seems to be called multiple times.
Here's an example of the results of the test code I'll paste below ...
12:48:12 PM: 3932: Entering Main
12:48:12 PM: 3932: Calling Test1 asnchronously
12:48:12 PM: 2064: Entering Test1
12:48:12 PM: 2064: Exiting Test1
12:48:12 PM: 2064: Entering Test1Callback
12:48:12 PM: 2064: Calling EndInvoke in Test1Callback
12:48:12 PM: 2064: Calling Test2 asynchronously
12:48:12 PM: 2064: Exiting Test1Callback
12:48:12 PM: 2064: Entering Test1
12:48:12 PM: 2064: Exiting Test1
12:48:12 PM: 2064: Entering Test2Callback
12:48:12 PM: 2064: Calling EndInvoke in Test2Callback
12:48:12 PM: 3932: Exiting Main
12:48:14 PM: 2064: Entering Test2Callback
12:48:14 PM: 2064: Calling EndInvoke in Test2Callback
Notice that Test1 is called multiple times. Ideally I would like to see this
executed once. This is the behaviour I'm trying to rectify. Can anyone
suggest what I'm doing wrong? Here's the code for the test app (please be
sure to cut the sample code and results from any replies to this post to
keep the size down).
Thanks in advance, Sam.
VB CONSOLE APP CODE ...
Imports System
Imports System.Diagnostics
Module MainModule
Private Delegate Sub Test1Delegate()
Private Delegate Sub Test2Delegate()
Sub Main()
Console.WriteLine(String.Format("{0}: {1}: Entering Main",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Console.WriteLine(String.Format("{0}: {1}: Calling Test1 asnchronously",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Dim method As New Test1Delegate(AddressOf Test1)
Dim result As IAsyncResult = method.BeginInvoke(New
AsyncCallback(AddressOf Test1Callback), method)
Do Until result.IsCompleted
'
Loop
Console.WriteLine(String.Format("{0}: {1}: Exiting Main",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Console.ReadLine()
End Sub
Private Sub Test1()
Console.WriteLine(String.Format("{0}: {1}: Entering Test1",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Console.WriteLine(String.Format("{0}: {1}: Exiting Test1",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
End Sub
Private Sub Test1Callback(ByVal ar As IAsyncResult)
Console.WriteLine(String.Format("{0}: {1}: Entering Test1Callback",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Console.WriteLine(String.Format("{0}: {1}: Calling EndInvoke in
Test1Callback", DateTime.Now.ToLongTimeString(),
AppDomain.GetCurrentThreadId))
Dim method As Test1Delegate = DirectCast(ar.AsyncState, Test1Delegate)
method.EndInvoke(ar)
Console.WriteLine(String.Format("{0}: {1}: Calling Test2
asynchronously", DateTime.Now.ToLongTimeString(),
AppDomain.GetCurrentThreadId))
Dim method2 As New Test2Delegate(AddressOf Test2)
Dim result As IAsyncResult = method.BeginInvoke(New
AsyncCallback(AddressOf Test2Callback), method)
Console.WriteLine(String.Format("{0}: {1}: Exiting Test1Callback",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
End Sub
Private Sub Test2()
Console.WriteLine(String.Format("{0}: {1}: Entering Test2",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Console.WriteLine(String.Format("{0}: {1}: Exiting Test2",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
End Sub
Private Sub Test2Callback(ByVal ar As IAsyncResult)
Console.WriteLine(String.Format("{0}: {1}: Entering Test2Callback",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Console.WriteLine(String.Format("{0}: {1}: Calling EndInvoke in
Test2Callback", DateTime.Now.ToLongTimeString(),
AppDomain.GetCurrentThreadId))
Dim method As Test2Delegate = DirectCast(ar.AsyncState, Test2Delegate)
method.EndInvoke(ar)
Console.WriteLine(String.Format("{0}: {1}: Exiting Test2Callback",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
End Sub
End Module
running into an issue. I need to asynchronously call a method (which I'm
doing with a delegate and BeginInvoke) and from the callback method, or at
some point after the EndInvoke has been called to end the asynchronous
operation I need to asynchronously call a different method.
I really want to keep this event based and use delegates and callbacks
rather than loop until completed, as there will be many instances of this
process running at the same time in parallel and I don't want to strain
resources.
The results are that the first method seems to be called multiple times.
Here's an example of the results of the test code I'll paste below ...
12:48:12 PM: 3932: Entering Main
12:48:12 PM: 3932: Calling Test1 asnchronously
12:48:12 PM: 2064: Entering Test1
12:48:12 PM: 2064: Exiting Test1
12:48:12 PM: 2064: Entering Test1Callback
12:48:12 PM: 2064: Calling EndInvoke in Test1Callback
12:48:12 PM: 2064: Calling Test2 asynchronously
12:48:12 PM: 2064: Exiting Test1Callback
12:48:12 PM: 2064: Entering Test1
12:48:12 PM: 2064: Exiting Test1
12:48:12 PM: 2064: Entering Test2Callback
12:48:12 PM: 2064: Calling EndInvoke in Test2Callback
12:48:12 PM: 3932: Exiting Main
12:48:14 PM: 2064: Entering Test2Callback
12:48:14 PM: 2064: Calling EndInvoke in Test2Callback
Notice that Test1 is called multiple times. Ideally I would like to see this
executed once. This is the behaviour I'm trying to rectify. Can anyone
suggest what I'm doing wrong? Here's the code for the test app (please be
sure to cut the sample code and results from any replies to this post to
keep the size down).
Thanks in advance, Sam.
VB CONSOLE APP CODE ...
Imports System
Imports System.Diagnostics
Module MainModule
Private Delegate Sub Test1Delegate()
Private Delegate Sub Test2Delegate()
Sub Main()
Console.WriteLine(String.Format("{0}: {1}: Entering Main",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Console.WriteLine(String.Format("{0}: {1}: Calling Test1 asnchronously",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Dim method As New Test1Delegate(AddressOf Test1)
Dim result As IAsyncResult = method.BeginInvoke(New
AsyncCallback(AddressOf Test1Callback), method)
Do Until result.IsCompleted
'
Loop
Console.WriteLine(String.Format("{0}: {1}: Exiting Main",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Console.ReadLine()
End Sub
Private Sub Test1()
Console.WriteLine(String.Format("{0}: {1}: Entering Test1",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Console.WriteLine(String.Format("{0}: {1}: Exiting Test1",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
End Sub
Private Sub Test1Callback(ByVal ar As IAsyncResult)
Console.WriteLine(String.Format("{0}: {1}: Entering Test1Callback",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Console.WriteLine(String.Format("{0}: {1}: Calling EndInvoke in
Test1Callback", DateTime.Now.ToLongTimeString(),
AppDomain.GetCurrentThreadId))
Dim method As Test1Delegate = DirectCast(ar.AsyncState, Test1Delegate)
method.EndInvoke(ar)
Console.WriteLine(String.Format("{0}: {1}: Calling Test2
asynchronously", DateTime.Now.ToLongTimeString(),
AppDomain.GetCurrentThreadId))
Dim method2 As New Test2Delegate(AddressOf Test2)
Dim result As IAsyncResult = method.BeginInvoke(New
AsyncCallback(AddressOf Test2Callback), method)
Console.WriteLine(String.Format("{0}: {1}: Exiting Test1Callback",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
End Sub
Private Sub Test2()
Console.WriteLine(String.Format("{0}: {1}: Entering Test2",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Console.WriteLine(String.Format("{0}: {1}: Exiting Test2",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
End Sub
Private Sub Test2Callback(ByVal ar As IAsyncResult)
Console.WriteLine(String.Format("{0}: {1}: Entering Test2Callback",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
Console.WriteLine(String.Format("{0}: {1}: Calling EndInvoke in
Test2Callback", DateTime.Now.ToLongTimeString(),
AppDomain.GetCurrentThreadId))
Dim method As Test2Delegate = DirectCast(ar.AsyncState, Test2Delegate)
method.EndInvoke(ar)
Console.WriteLine(String.Format("{0}: {1}: Exiting Test2Callback",
DateTime.Now.ToLongTimeString(), AppDomain.GetCurrentThreadId))
End Sub
End Module