herbert
2004-12-05 15:12:25 UTC
Being a VB.NET programmer I wandered what is MTA and STA is all about for my
daily life, cause in my 30+ books about .NET its only mentioned it in three
lines.
However now I have a problem using events to synch multiple threads.
Im refering to a code snipped in MS-PRESS NEtwork programming for the .NET
Framework, ISBN ...1959-X, page 58 / 59.
The text goes about using Events to sync multiple threads in the threadpool
with the foreground thread and the code (yes, you guess it) then shows how to
sync one thread.
So I completed the example (see below). I use a console app, as I know that
there are problems with Windows forms in this case. I cannot declare the
callback routine shared cause a console module does not allow it (why not, by
the way?)
When I run the app, I get a message which (translated to English) says
something like: "WaitAll for several handles not supported in STA."
That's true as the app runs correctly with a single threadpool thread. (code
below)
So what's happening inside?
How do I make my console module MTA?
Where is a comprehensive, all-in-one explanation for the guy in the basement
IT dept?
thanks herbert
Imports System.Threading
Module Module1
Sub Main()
'this delegate wraps the method to be executed in the threadpool
Dim CallbackMethod1 As WaitCallback = New WaitCallback(AddressOf
MyThreadPoolMethod1)
'Dim CallbackMethod2 As WaitCallback = New WaitCallback(AddressOf
MyThreadPoolMethod2)
'Dim CallbackMethod3 As WaitCallback = New WaitCallback(AddressOf
MyThreadPoolMethod3)
'create an array of wait handle objects to wait on
Dim WaitHandleArray(2) As WaitHandle 'allow three threads in
threadpool to synchronize with foreground thread
'Assign a manual reset event object to the array (one for each
thread in the pool)
WaitHandleArray(0) = New ManualResetEvent(False)
'WaitHandleArray(1) = New ManualResetEvent(False)
'WaitHandleArray(2) = New ManualResetEvent(False)
'use the threadpool
'pass the manual reset event object to the wait callback method
(this is the method executed in the threadpool)
Console.WriteLine("queue tasks to threadpool.")
ThreadPool.QueueUserWorkItem(CallbackMethod1, WaitHandleArray(0))
'ThreadPool.QueueUserWorkItem(CallbackMethod2, WaitHandleArray(1))
'ThreadPool.QueueUserWorkItem(CallbackMethod3, WaitHandleArray(2))
'Wait for the callback method to complete
Console.WriteLine("wait for all three threads to complete.")
WaitHandle.WaitAll(WaitHandleArray)
Console.WriteLine("All three threads completed.")
Console.ReadLine()
End Sub
Sub MyThreadPoolMethod1(ByVal State As Object)
'assume a manual reset event object was passed in the State parameter
Dim MRE As ManualResetEvent = CType(State, ManualResetEvent)
'do something useful here
Thread.Sleep(1000)
'signal the manual reset event object when the callback routine is
finished
MRE.Set()
End Sub
Sub MyThreadPoolMethod2(ByVal State As Object)
'assume a manual reset event object was passed in the State parameter
Dim MRE As ManualResetEvent = CType(State, ManualResetEvent)
'do something useful here
Thread.Sleep(1000)
'signal the manual reset event object when the callback routine is
finished
MRE.Set()
End Sub
Sub MyThreadPoolMethod3(ByVal State As Object)
'assume a manual reset event object was passed in the State parameter
Dim MRE As ManualResetEvent = CType(State, ManualResetEvent)
'do something useful here
Thread.Sleep(1000)
'signal the manual reset event object when the callback routine is
finished
MRE.Set()
End Sub
End Module
daily life, cause in my 30+ books about .NET its only mentioned it in three
lines.
However now I have a problem using events to synch multiple threads.
Im refering to a code snipped in MS-PRESS NEtwork programming for the .NET
Framework, ISBN ...1959-X, page 58 / 59.
The text goes about using Events to sync multiple threads in the threadpool
with the foreground thread and the code (yes, you guess it) then shows how to
sync one thread.
So I completed the example (see below). I use a console app, as I know that
there are problems with Windows forms in this case. I cannot declare the
callback routine shared cause a console module does not allow it (why not, by
the way?)
When I run the app, I get a message which (translated to English) says
something like: "WaitAll for several handles not supported in STA."
That's true as the app runs correctly with a single threadpool thread. (code
below)
So what's happening inside?
How do I make my console module MTA?
Where is a comprehensive, all-in-one explanation for the guy in the basement
IT dept?
thanks herbert
Imports System.Threading
Module Module1
Sub Main()
'this delegate wraps the method to be executed in the threadpool
Dim CallbackMethod1 As WaitCallback = New WaitCallback(AddressOf
MyThreadPoolMethod1)
'Dim CallbackMethod2 As WaitCallback = New WaitCallback(AddressOf
MyThreadPoolMethod2)
'Dim CallbackMethod3 As WaitCallback = New WaitCallback(AddressOf
MyThreadPoolMethod3)
'create an array of wait handle objects to wait on
Dim WaitHandleArray(2) As WaitHandle 'allow three threads in
threadpool to synchronize with foreground thread
'Assign a manual reset event object to the array (one for each
thread in the pool)
WaitHandleArray(0) = New ManualResetEvent(False)
'WaitHandleArray(1) = New ManualResetEvent(False)
'WaitHandleArray(2) = New ManualResetEvent(False)
'use the threadpool
'pass the manual reset event object to the wait callback method
(this is the method executed in the threadpool)
Console.WriteLine("queue tasks to threadpool.")
ThreadPool.QueueUserWorkItem(CallbackMethod1, WaitHandleArray(0))
'ThreadPool.QueueUserWorkItem(CallbackMethod2, WaitHandleArray(1))
'ThreadPool.QueueUserWorkItem(CallbackMethod3, WaitHandleArray(2))
'Wait for the callback method to complete
Console.WriteLine("wait for all three threads to complete.")
WaitHandle.WaitAll(WaitHandleArray)
Console.WriteLine("All three threads completed.")
Console.ReadLine()
End Sub
Sub MyThreadPoolMethod1(ByVal State As Object)
'assume a manual reset event object was passed in the State parameter
Dim MRE As ManualResetEvent = CType(State, ManualResetEvent)
'do something useful here
Thread.Sleep(1000)
'signal the manual reset event object when the callback routine is
finished
MRE.Set()
End Sub
Sub MyThreadPoolMethod2(ByVal State As Object)
'assume a manual reset event object was passed in the State parameter
Dim MRE As ManualResetEvent = CType(State, ManualResetEvent)
'do something useful here
Thread.Sleep(1000)
'signal the manual reset event object when the callback routine is
finished
MRE.Set()
End Sub
Sub MyThreadPoolMethod3(ByVal State As Object)
'assume a manual reset event object was passed in the State parameter
Dim MRE As ManualResetEvent = CType(State, ManualResetEvent)
'do something useful here
Thread.Sleep(1000)
'signal the manual reset event object when the callback routine is
finished
MRE.Set()
End Sub
End Module