Rounded Rectangular Callout: new Thread instance

Rounded Rectangular Callout: new Thread
Rounded Rectangular Callout: IsBackGround
Rounded Rectangular Callout: Resume
Rounded Rectangular Callout: Suspend
Rounded Rectangular Callout: wait/sleep/join
Rounded Rectangular Callout: signal time out
Rounded Rectangular Callout: wait/sleep/join
abort
Rounded Rectangular Callout: wait/sleep/join
suspend-resume

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

   

Suspend and Resume

A thread can be explicitly suspended and resumed via the methods Thread.Suspend and Thread.Resume. This mechanism is completely separate to that of blocking discussed previously. Both systems are independent and operate in parallel.

A thread can suspend itself or another thread. Calling Suspend results in the thread briefly entering the SuspendRequested state, then upon reaching a point safe for garbage collection, it enters the Suspended state. From there, it can be resumed only via another thread that calls its Resume method. Resume will work only on a suspended thread, not a blocked thread.

From .NET 2.0, Suspend and Resume have been deprecated, their use discouraged because of the danger inherent in arbitrarily suspending another thread. If a thread holding a lock on a critical resource is suspended, the whole application (or computer) can deadlock. This is far more dangerous than calling Abort – which would result in any such locks being released – at least theoretically – by virtue of code in finally blocks.

It is, however, safe to call Suspend on the current thread – and in doing so one can implement a simple synchronization mechanism – with a worker thread in a loop – performing a task, calling Suspend on itself, then waiting to be resumed (“woken up”) by the main thread when another task is ready. The difficulty, though, is in testing whether or not the worker is suspended. Consider the following code:

worker.NextTask = "MowTheLawn";
if ((worker.ThreadState & ThreadState.Suspended) > 0)
  worker.Resume;
else
  // We cannot call Resume as the thread's already running.
  // Signal the worker with a flag instead:
  worker.AnotherTaskAwaits = true;

This is horribly thread-unsafe – the code could be preempted at any point in these five lines – during which the worker could march on in and change its state. While it can be worked around, the solution is more complex than the alternative – using a synchronization construct such as an AutoResetEvent or Monitor.Wait. This makes Suspend and Resume useless on all counts.

The deprecated Suspend and Resume methods have two modes – dangerous and useless!