I've been wondering is there any way in which we can move BackgroundWorker to sleep and resume it again just like thread. I've searched in many forums in vain. None of them show any method which would do that. I checked Microsoft documentation and found out there isn't any predefined methods.
I know the workarounds by using resetEvents. Just asking for any other possible and much easier way.
If you use Task instead of BackgroundWorker you can use the PauseTokenSource.
This class is similar to the built in CancellationTokenSource only suitable for pausing tasks and not canceling them.
PauseTokenSource API was built exactly for what you need and it's API can replace your usage of Thread.Sleep and all the signaling events.
Other option besides PauseTokenSource can use AsyncManualResetEvent, the mechanism internal is quite similar but they differ in the API. I think that PauseTokenSource is much more convenient and especially built for this purpose, more info here.
From within your DoWork handler, you can call Thread.Sleep() whenever you want. If you want, from the GUI, to be able to signal the worker to pause, set up a concurrent queue, feed your sleep requests into it from the GUI thread, and have your DoWork handler check the queue periodically, pausing as requested.
(If you want to pause the BackgroundWorker until signaled again rather than for a certain period of time, you can do that in a similar way--just periodically check the queue for a "restart" command and sleep a few milliseconds before checking again.)
Related
I am using a TaskFactory to manage my program's tasks. I would like to add a task to the queue that will start running after X minutes. Can it be done using .Net's standard tools or do I need to use a custom library for that.
Thanks
Yes this can be quite easily achieved. Look into some articles of basic multi-threading to ensure your UI is still responsive when scheduling/running these tasks. As has already been mentioned - the Timer control will do the trick.
The Programmers Heaven EBook on C#'s multi-threading section has enough in it to do what you want with regards to the multi-threading.
If you objective is to run something after a while you could use the Timer
Start the Timer, when the timer has elapsed, stop the Timer.
You could create a single-shot Timer that creates your Task when it fires. This means you won't be blocking a thread while you are waiting.
If you are writing a scheduler, you might want to look at Quartz.NET
I am using ThreadPool in .NET to make some web request in the background, and I want to have a "Stop" button to cancel all the threads even if they are in the middle of making a request, so a simple bool wont do the job.
How can I do that?
Your situation is pretty much the canonical use-case for the Cancellation model in the .NET framework.
The idea is that you create a CancellationToken object and make it available to the operation that you might want to cancel. Your operation occasionally checks the token's IsCancellationRequested property, or calls ThrowIfCancellationRequested.
You can create a CancellationToken, and request cancellation through it, by using the CancellationTokenSource class.
This cancellation model integrates nicely with the .NET Task Parallel Library, and is pretty lightweight, more so than using system objects such as ManualResetEvent (though that is a perfectly valid solution too).
The correct way to handle this is to have a flag object that you signal.
The code running in those threads needs to check that flag periodically to see if it should exit.
For instance, a ManualResetEvent object is suitable for this.
You could then ask the threads to exit like this:
evt.Set();
and inside the threads you would check for it like this:
if (evt.WaitOne(0))
return; // or otherwise exit the thread
Secondly, since you're using the thread pool, what happens is that all the items you've queued up will still be processed, but if you add the if-statement above to the very start of the thread method, it will exit immediately. If that is not good enough you should build your own system using normal threads, that way you have complete control.
Oh, and just to make sure, do not use Thread.Abort. Ask the threads to exit nicely, do not outright kill them.
If you are going to stop/cancel something processing in another thread, ThreadPool is not the best choice, you should use Thread instead, and manage all of them in a container(e.g. a global List<Thread>), that guarantees you have full control of all the threads.
I have created an array of threads and started all of them. How to know whether all threads have completed work. I don't want to use thread.wait or thread.join.
If you are using .NET 4 you could use the Task Parallel Library and the ContinueWhenAll method.
You'd have to modify your threads to be represented as Task's. Tasks are easier to work with then threads. Usually you do not have to worry about lower-level things as you are forced to do now like scheduling or waiting for things to complete.
Well, you can test Thread.IsAlive - but that will be out of date as soon as you've tested it, of course. You could keep a list of "currently alive" threads, and remove them one at a time when they stop, sleeping between test runs. For more detailed information you can use Thread.ThreadState.
What's the bigger picture here? What are you trying to achieve, and why don't you want to call Thread.Join (potentially with a timeout)?
What about MyThread.ThreadState == System.Threading.ThreadState.Stopped ?
Have the threads call back to the class that you started them in to signal that they are done
You could use the ThreadPool class instead of an array, and use the 'GetAvailableThreads' method to check if all threads are available. See:
ThreadPool class.
if you want to intercept the work asynchronously you can use BackgroundWorkers all of which have a RunWorkerCompleted event and a Error and Cancelled properties in the event args
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
What is the best approach in using a timer. Use a System.Timer.Timer class or use a single Thread in a non-terminating loop with a Thread.Sleep statement?
Thanks in advance
In general, use the components that are already there if they serve your needs. However, System.Threading.Timer uses the .NET thread pool, so any of the following conditions would make it a poor candidate:
You require a STA thread (all ThreadPool threads are MTA)
You require that all occurrences of your repeated task run on the same thread
You want to assign a particular priority (lower or higher) to your tasks
Your tasks are particularly long-running or utilize non-trivial blocks
Use a Timer. It's there, specifically for that purpose, so why wouldn't you use it?
The two methods you refer to are used for different results.
Timers will fire the event and invoke your method on a scheduled interval. They could invoke your method whilst another instance of it is running unless you stop the timer at the start of your processing (DoWork) and start it again when you're done (but then you might miss the timed events).
A method that loops and sleeps will not be invoked when it's busy. The "advantage" here is that you can DoWork, then find that the next timer event has already passed and DoWork immediately again. The alternative is that you have rest periods where you sleep a specified amount of time regardless of how long your DoWork method took.
How to cancel an asynchronous call? The .NET APM doesn't seem to support this operation.
I have the following loop in my code which spawns multiple threads on the ThreadPool. When I click a button on my UI, I would like these threads (or asynchronous calls) to end.
foreach (var sku in skus)
{
loadSku.BeginInvoke(...
}
Is there any elegant solution other than creating a global "Cancel flag" and having the asynchronous methods to look for it?
A "cancel flag" is the way to do it, though not a global one, necessarily. The unavoidable point is that you need some way to signal to the thread that it should stop what it's doing.
In the case of BeginInvoke, this is hard to do with anything but a global flag, because the work is carried out on the threadpool, and you don't know which thread. You have a couple of options (in order of preference):
Use the BackgroundWorker instead of BeginInvoke. This has cancellation functionality baked-in. This has other benefits, like progress monitoring, and "Work complete" callbacks. It also nicely handles exceptions.
Use ThreadPool.QueueUserWorkItem, passing in an object as the state that has a Cancel() method that sets a Cancelled flag that the executing code can check. Of course you'll need to keep a reference to the state object so you can call Cancel() on it (which is something the BackgroundWorker does for you - you have a component on your form. (Thanks to Fredrik for reminding about this).
Create your own ThreadStart delegate, passing in a state object as with option 2.
If you're lookin for a "TerminateAsnyc" method, you won't find one. Therefore, no, there's probably no elegant way while using Control.BeginInvoke/EndInvoke. Thus, I'd put the boolean flag on the UI thread and have the delegate being executed asynchronously check that flag periodically while it's executing.
However, you might check into using background worker threads.
There are definitely other solutions, although I don't know that I would call them "elegant".
you could call Abort or Interrupt on the thread but these can have some negative side effects. Personally, for something like this I prefer to use BackgroundWorker if possible. It has a Cancel feature but it is similar to what you mentioned - a bool flag in the class that you have to periodically check for in the executing code (at least it's not a global flag). This post on stopping threads in .NET is a bit old but goes over some of the pitfalls of the other options I mentioned above.