G
Guest
We have a requirement to implement multithreaded processing for a function.
ThreadPool is used to implement multithreading in order to avoid the over
head of creating and destroying Threads dynamically.
A function will Queues the method calls to the default ThreadPool. If the
number of method calls is more than the ThreadPool size, it will get queued
for getting a slot in the ThreadPool.
Our requirement is to implement a Time-out in the waitQueue of the
ThreadPool. If a request is queued in the ThreadPool for a pre-defined amount
of time, it should get Timeout, notify the user and that particular request
should not go inside the ThreadPool again. In short, if a thread is not
available, the thread manager should wait for one to become available. If
none become available within a time period, then the process would fail out,
leaving the existing threads to complete
For implementing this we used ThreadPool.RegisterWaitForSingleObject method.
The problem here is that even though we can specify a Time out in
millisecond, the Timeout delegate also will get queued in the ThreadPool and
the Original request will get executed before the Timeout delegate. We have
to give some kind of priority to the Timeout delegate, so that if a request
gets Timeout, the same request will not get processed.
Sample Code which simulates the situation:
private void btnStart_Click(object sender, EventArgs e)
{
AutoResetEvent arEvent = new AutoResetEvent(false);
ThreadPool.SetMaxThreads(2, 2);
for (int i = 0; i < 10; i++)
{
ThreadPool.RegisterWaitForSingleObject(arEvent, new
WaitOrTimerCallback(Print), “Objectâ€+ i , 2000, true);
arEvent.Set();
//Time out is set as 2 seconds and ThreadPool size is 2
}
}
Public void Print(object state, bool timedOut)
{
TimeSpan waitTime = DateTime.Now.Subtract(tInfo.TaskQueuedTime);
if (waitTime.TotalMilliseconds < TIMEOUT)
{
MessageBox.Show("Executing " + state.ToString());
Thread.Sleep(3000);
//Thread is taking more than 3 seconds to complete the task
}
else
{
Console.out.WriteLine("Time Out " + state.ToString());
}
}
Based on our requrement, the ThreadPool should show MessageBox only for
first two items in the queue and it should write the Time Out in console for
all the remaining eight items in the queue. But its actual behaviour is that,
Its showing MessageBox for all the ten items in the Queue and shows Time Out
for the last eight items. The Time Out for last eight items are invoked after
showing all the ten MessageBoxes.
The reason why its happened is because, even the TimeOut delegate is also
getting queued in the ThreadPool.
Can anyone please suggest a solution to resolve this issue.
Thanking you in advance
ThreadPool is used to implement multithreading in order to avoid the over
head of creating and destroying Threads dynamically.
A function will Queues the method calls to the default ThreadPool. If the
number of method calls is more than the ThreadPool size, it will get queued
for getting a slot in the ThreadPool.
Our requirement is to implement a Time-out in the waitQueue of the
ThreadPool. If a request is queued in the ThreadPool for a pre-defined amount
of time, it should get Timeout, notify the user and that particular request
should not go inside the ThreadPool again. In short, if a thread is not
available, the thread manager should wait for one to become available. If
none become available within a time period, then the process would fail out,
leaving the existing threads to complete
For implementing this we used ThreadPool.RegisterWaitForSingleObject method.
The problem here is that even though we can specify a Time out in
millisecond, the Timeout delegate also will get queued in the ThreadPool and
the Original request will get executed before the Timeout delegate. We have
to give some kind of priority to the Timeout delegate, so that if a request
gets Timeout, the same request will not get processed.
Sample Code which simulates the situation:
private void btnStart_Click(object sender, EventArgs e)
{
AutoResetEvent arEvent = new AutoResetEvent(false);
ThreadPool.SetMaxThreads(2, 2);
for (int i = 0; i < 10; i++)
{
ThreadPool.RegisterWaitForSingleObject(arEvent, new
WaitOrTimerCallback(Print), “Objectâ€+ i , 2000, true);
arEvent.Set();
//Time out is set as 2 seconds and ThreadPool size is 2
}
}
Public void Print(object state, bool timedOut)
{
TimeSpan waitTime = DateTime.Now.Subtract(tInfo.TaskQueuedTime);
if (waitTime.TotalMilliseconds < TIMEOUT)
{
MessageBox.Show("Executing " + state.ToString());
Thread.Sleep(3000);
//Thread is taking more than 3 seconds to complete the task
}
else
{
Console.out.WriteLine("Time Out " + state.ToString());
}
}
Based on our requrement, the ThreadPool should show MessageBox only for
first two items in the queue and it should write the Time Out in console for
all the remaining eight items in the queue. But its actual behaviour is that,
Its showing MessageBox for all the ten items in the Queue and shows Time Out
for the last eight items. The Time Out for last eight items are invoked after
showing all the ten MessageBoxes.
The reason why its happened is because, even the TimeOut delegate is also
getting queued in the ThreadPool.
Can anyone please suggest a solution to resolve this issue.
Thanking you in advance