|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Implement a Time-out in the waitQueue of the ThreadPoolThreadPool 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 This is why the thread pool should not be used for long running tasks. The
long running tasks can fill the thread pool and not allow things like timer callbacks to run - causing blocking issues. You can't even use one of the System timers because the callback happens on the TP - which I presume could be filled processing long running print jobs. One solution here is use your own thread pool or just a couple worker threads and blocking queue. Your state object could have a Cancel property on it, so you can cancel the task after some timeout if it has not run yet. When a worker thread gets to the work item, it will see it is cancelled and just move on to the next item. -- Show quoteWilliam Stacey [MVP] "Ashish" <ash***@discussions.microsoft.com.> wrote in message news:A084829C-5C40-452B-8247-5A1A2F792C4E@microsoft.com... | 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 | | | "Ashish" <ash***@discussions.microsoft.com.> wrote [Thread Pool is full of blocking events, and things are now broken]> Can anyone please suggest a solution to resolve this issue. You can't use the ThreadPool for long running operations, or for operations > Thanking you in advance that have the potential to block. As soon as you do this, things can fall apart, because you and the .Net framework are sharing the threadpool, and both of you rely on having available threads to use. The long and short of it is that you have two real options: 1 - Make all of your thread pool operations 100% async 2 - Don't use the system thread pool. I wrote up a detailed blog entry on this a few months back that can be found at: http://www.coversant.net/dotnetnuke/Default.aspx?tabid=88&EntryID=8 As an aside, Jeff Richter has put together a "Power Threading Library" you should take a look at. He's got a lock type in there that's pretty close to what I think you're looking for. You can find his library at: http://www.wintellect.com/ (look for the "Power Threading" section in for "For Developers" list on the right hand side. Chris,
Good blog. Have you seen what's available in the Currency and Coordination Runtime (CCR) developed by Microsoft? You said you wanted the ability to create different instances of a thread pool. That's built into the CCR using the Dispatcher class. http://channel9.msdn.com/wiki/default.aspx/Channel9.ConcurrencyRuntime http://msdn.microsoft.com/msdnmag/issues/06/09/concurrentaffairs/default.aspx Brian Chris Mullins wrote: Show quote > I wrote up a detailed blog entry on this a few months back that can be found > at: http://www.coversant.net/dotnetnuke/Default.aspx?tabid=88&EntryID=8 I'll second the CCR. Is a great library. Having been doing much with it
lately. However not having solid redist plans for the CCR right now is kinda scary. -- William Stacey [MVP] "Brian Gideon" <briangid***@yahoo.com> wrote in message http://msdn.microsoft.com/msdnmag/issues/06/09/concurrentaffairs/default.aspxnews:1157734617.190335.186090@m79g2000cwm.googlegroups.com... | Chris, | | Good blog. Have you seen what's available in the Currency and | Coordination Runtime (CCR) developed by Microsoft? You said you wanted | the ability to create different instances of a thread pool. That's | built into the CCR using the Dispatcher class. | | http://channel9.msdn.com/wiki/default.aspx/Channel9.ConcurrencyRuntime | Show quote | | Brian | | Chris Mullins wrote: | > I wrote up a detailed blog entry on this a few months back that can be found | > at: http://www.coversant.net/dotnetnuke/Default.aspx?tabid=88&EntryID=8 |
Other interesting topics
|
|||||||||||||||||||||||