Your code doesn't work becaues you have misused WaitHandles. The purpose of a wait handle is to set a synchronized flag to let
another thread know that a process has been completed or that the application's "state" has changed.
The WaitHandles that you are using in your code example are never "set". This is why "Threads Timed Out" will always be written to
the output.
I revisited my code to figure out why you had trouble running this using multiple threads. It seems that I have made a mistake and
forgot a character (an important one at that):
The following lines are the context of the error:
if (ev.WaitOne(10000, false))
{
// timeout expired!
}
It should be changed to:
if (!ev.WaitOne(10000, false))
// WaitOne returns false if the specified time period elapsis before the handle is signaled
{
// timeout expired!
}
Try again using multiple threads and it should work just fine (with the correction). Here's an example:
The ouptut for the following code will be:
ThreadPooledCall: Call #0
Pooled: True
ThreadPooledCall: Call #1
Pooled: True
ThreadPooledCall: Call #2
Pooled: True
ThreadPooledCall: Call #3
Pooled: True
ThreadPooledCall: Call #4
Pooled: True
ThreadPooledCall: Call #5
Pooled: True
ThreadPooledCall: Call #6
Pooled: True
ThreadPooledCall: Call #7
Pooled: True
ThreadPooledCall: Call #8
Pooled: True
ThreadPooledCall: Call #9
Pooled: True
Finished.
Here's the code:
using System;
using System.Threading;
using System.Diagnostics;
namespace TestConsole
{
public class ThreadSyncTest
{
private AutoResetEvent ev = new AutoResetEvent(false);
private delegate void ThreadPooledCallInvoker(string Data);
public void ThreadPooledCall(string Data)
{
lock (this)
// synchronize access to the Debug class (it is not thread-safe)
{
Debug.WriteLine(string.Format("ThreadPooledCall: {0}", Data));
Debug.Indent();
Debug.WriteLine(string.Format("Pooled: {0}", Thread.CurrentThread.IsThreadPoolThread));
Debug.Unindent();
}
// Block the thread for 1 second
System.Threading.Thread.Sleep(1000);
// Alert waiting threads we are complete
ev.Set();
}
public void DoStuff()
{
for (int i = 0; i < 10; i++)
new ThreadPooledCallInvoker(ThreadPooledCall).BeginInvoke("Call #" + i, null, null);
for (int i = 0; i < 10; i++)
// wait till each background thread completes for up to 10 seconds
if (!ev.WaitOne(10000, false))
{
Debug.WriteLine("Timeout Expired.");
}
Debug.WriteLine("Finished.");
}
}
}
--
Dave Sexton
dave@www..jwaonline..com
-----------------------------------------------------------------------
[quoted text, click to view] <orekinbck@yahoo.com.au> wrote in message news:1114942973.927399.7330@f14g2000cwb.googlegroups.com...
> Hi Dave & Richard
>
> The Beta site is having some errors, so this might be the first time
> this reply appears, or the Fourth!
>
> Thanks for your response. I could get the code you supplied working
> with one thread, but had problems using AutoResetEvent with more than
> one worker thread. What do you think of this solution (you should be
> able to cut paste and compile this code)?
>
> using System;
> using System.Threading;
> using System.Diagnostics;
>
> namespace AutoResetEvent_Examples
> {
> class MyMainClass
> {
> private delegate void ThreadPooledCallInvoker();
>
> public static void ThreadPooledCall()
> {
> Debug.WriteLine("Hello from ThreadPooledCall!");
> Thread.Sleep(500);
> }
>
> static void Main()
> {
> // Create the ThreadPooledCallInvoker delegates.
> ThreadPooledCallInvoker dlgt = new
> ThreadPooledCallInvoker(ThreadPooledCall);
> ThreadPooledCallInvoker dlgt2 = new
> ThreadPooledCallInvoker(ThreadPooledCall);
>
> // Get the delegates going
> IAsyncResult ar = dlgt.BeginInvoke(null,null);
> IAsyncResult ar2 = dlgt2.BeginInvoke(null,null);
> Thread.Sleep(0); //Allow Delegates to get started
>
> //Create WaitHandleArray
> WaitHandle[] myWaiters = new WaitHandle[2];
> myWaiters[0] = ar.AsyncWaitHandle;
> myWaiters[1] = ar2.AsyncWaitHandle;
>
> if (!WaitHandle.WaitAll(myWaiters,1000,false))
> {
> //Timed Out
> Debug.WriteLine("Threads Timed Out");
> }
> else
> {
> Debug.WriteLine("Threads Completed");
> dlgt.EndInvoke(ar);
> dlgt2.EndInvoke(ar2);
> }
> }
> }
> }
>
> Thanks
> Bill
>