My model of how threads work is that some ThreadManager gives each thread a turn. When it's a thread's turn, it gets to execute a few lines of code.
To pause a thread, couldn't one just have the ThreadManager (momentarily) stop allowing that thread to have a turn?
To abort a thread, couldn't the ThreadManager just never give that thread another turn?
What's the problem?
Quote from MSDN about pausing threads:
You have no way of knowing what code a
thread is executing when you suspend
it. If you suspend a thread while it
holds locks during a security
permission evaluation, other threads
in the AppDomain might be blocked. If
you suspend a thread while it is
executing a class constructor, other
threads in the AppDomain that attempt
to use that class are blocked.
Deadlocks can occur very easily.
Aborted thread can lead to unpredicted circumstances. There is a good article about this: http://www.bluebytesoftware.com/blog/2009/03/13/ManagedCodeAndAsynchronousExceptionHardening.aspx
I agree with Alex, but to elaborate further, if you need to "pause" a thread, it will probably be better to look at some sort of locking mechanism like Semaphores, Mutexes, or one of the many other ones available.
But, without knowing your code, Windows is a preemptive multitasking environment. Usually this is not needed, just let your threads run and the underlying OS and scheduler will make sure all your tasks get a fair turn.
Related
MSDN documentation indicates that threads started by the TPL will enjoy better scheduling. However, since the threads are based upon ThreadPool, they will be implemented as background threads.
Now, there are some tasks I would like to be carried out in parallel, but it is imperative that these tasks be carried out until completion.
So, how do I create such tasks that are essentially foreground threads, but still enjoy the enhanced scheduling provided by the TPL?
You could write your own TaskScheduler implementation. Have a look in the TaskScheduler documentation for an example of implementing a TaskScheduler - hopefully it's relatively simple from there.
The TPL does not really give you Threads, it lets you create Tasks. Tasks can be executed on different threads, so Task != Thread.
As with the plain Threadpool, it would not be a good idea to change any Thread-properties.
But you problem could be easily solved by Waiting for any outstanding tasks from the main thread. You usually want to catch and handle their exceptions too.
The IsBackground property can be assigned to. I'm not sure if this is "okay" or "not-pants-on-head-dumb" though.
Happy coding.
It is imperative that these tasks be
carried out until completion.
I assume you mean that you want to make sure those tasks complete even if the primary thread is shut down?
I wouldn't suggest depending on the foreground thread staying active if the main thread shuts down. Under normal circumstances, you can keep the main thread active, waiting for the tasks to complete. You can also write a handler that can trap unhandled exceptions and do a graceful shutdown--including waiting for the tasks to complete. If something escapes your unhandled exceptions trap, then your process is probably so corrupt that you shouldn't trust whatever results the tasks deliver.
And, of course, nothing you do will prevent a user from shutting down the threads using Task Manager or something similar.
I just want to know how we can kill the BackgroundWorker Thread once it finished up with its associated tasks.
Is there any method like Kill or Abort or something else which can help?
Why are you worried about closing the thread after the task is already completed?
The thread is cleaned up in garbage collection. Calling Dispose() will help it probably be cleaned up sooner and is 'best practice'.
BackgroundWorker tasks are meant to be used on WinForms or using ThreadPool.QueueUserWorkItem(...) which will handle the lifecycle of the thread automatically internally.
See this related question: How to "kill" background worker completely?
No, you can't in general kill the thread that the BackgroundWorker was running on. That thread is part of ThreadPool. The ThreadPool manages the threads and decides when it should allocate more or get rid of some. You don't need to worry about killing the thread.
Which shouldn't be a problem. It's not like the thread is using any CPU time while it's idle. The small amount of system resources it's occupying won't be noticed.
I wanted to try my luck in threading with C#, I know a few things about threading in C.
So I just wanted to ask if i wanted to terminate a thread, I should do it with smt.Abort()
or it will "kill itself" after the function ends?
Also, is there something like pthread_exit() in C in C#?
Thread.Abort will "kill" the thread, but this is roughly equivalent to:
Scenario: You want to turn off your computer
Solution: You strap dynamite to your computer, light it, and run.
It's FAR better to trigger an "exit condition", either via CancellationTokenSource.Cancel, setting some (safely accessed) "is running" bool, etc., and calling Thread.Join. This is more like:
Scenario: You want to turn off your computer
Solution: You click start, shut down, and wait until the computer powers down.
You don't need to terminate a thread manually once the function has ended.
If you spawn up a thread to run a method, once the method has returned the thread will be shut down automatically as it has nothing further to execute.*
You can of course, manually abort a thread by simply calling Abort(), but this is pretty much un-recommended due to potential thread state corruption due to unreliable determination of where a thread is at in its current execution state. If you need to handle the killing of threads yourself, you may be best looking into using a CancellationToken. You could also read up on the Cancellation of Managed Threads article on MSDN.
** That is, unless, you're using a ThreadPool to perform your work. You shouldn't worry about aborting these threads as they're reused across different queued tasks.
Terminating a thread externally (from outside the thread) is a bad idea; you never know what the thread was in the middle of doing when you kill it asynchronously. In C#, if your thread function returns, the thread ends.
This MSDN article How to: Create and Terminate Threads (C# Programming Guide) has some notes and some sample code that you will probably find helpful.
Thread.Abort()
Thread.Join();
Thread = null;
Is there any way to find that
how many threads are waiting on semaphore?
how many threads have currently occupied semaphore?
if i use threadpool thread to wait on semaphore, how to let main thread wait until threadpool thread is finished.
Thanks.
This is forbidden knowledge in thread synchronization. Because it is utterly impossible to ever make this accurate. It represents an unsolvable race condition. When you use Habjan's approach, you'll conclude that there are, say, two threads waiting. A microsecond later another thread calls WaitOne() and there are three. But you'll make decisions based on that stale value.
Race conditions are nothing to mess with, they are incredibly hard to debug. They have a habit of making your code fail only once a week. As soon as you add instrumenting code to try to diagnose the reason your code fails, they'll stop occurring because that added code changed the timing.
Never do this.
So my question is how to implement cancel/interrupt feature into all (I mean ALL) thread workers in your application in best and most elegant way?
It's not important if it's an HttpWebRequest, IO operation or calculation. User should have an possibility to cancel every action/thread at any moment.
Use .NET 4.0 Tasks with CancellationTokens - they are the new universal cancellation system.
User should have an possibility to
cancel every action/thread at any
moment.
Threading is a practice, not a design... and believe me it has been tried as a design, but it failed miserably. The basic problem with simply canceling any action at any moment is that in a multithreaded environment it's just evil! Imagine that you have a section of code guarded by a lock and you have two threads running in parallel:
Thread 1 acquires the lock.
Thread 2 waits until the lock is released so it can acquire it.
Thread 1 is canceled while it's holding the lock and it doesn't release the lock.
DEADLOCK: Thread 2 is waiting for the lock which will never be released.
This is the simplest example and technically we can take care of this situation in the design, i.e. automatically release any locks that the thread has acquired, but instead of locks think of object states, resource utilization, client dependencies, etc. If your thread is modifying a big object and it's canceled in the middle of the modification, then the state of the object may be inconsistent, the resource which you're utilizing might get hung up, the client depending on that thread might crash... there is a slew of things which can happen and there is simply no way to design for them. In this case you make it a practice to manage the threads: you ensure a safe cancellation of your threads.
Others have already mentioned various methods for starting threads that can be canceled, but I just wanted to touch on the principles. Even in the cases where there is a way to cancel your threads, you still have to keep in mind that you're responsible for determining the safest way to cancel your thread.
It's not important if it's an HttpWebRequest, IO operation or calculation.
I hope now you understand why it's the MOST important thing! Unless you specifically know what your thread is doing, then there is no safe way to automatically cancel it.
P.S.
One thing to remember is that if you don't want hanging threads then for each one of them you can set the Thread.IsBackground flag to true and they will automatically be closed when your application exits.
Your worker threads need a way to check with your main thread to see if they should keep going. One way is to share a static volatile bool that's set by your UI and periodically checked by the worker threads.
My preference is to create your own threads that run instances of a worker class that periodically invoke a callback method provided by your main thread. This callback returns a value that tells the worker to continue, pause, or stop.
Avoid the temptation to use Thread.Abort() to kill worker threads: Manipulating a thread from a different thread.