How to Indefinitely Pause a Thread

Is there a way to indefinitely pause a thread?

Never, ever use Thread.Suspend. The major problem with it is that 99% of the time you can't know what that thread is doing when you suspend it. If that thread holds a lock, you make it easier to get into a deadlock situation, etc. Keep in mind that code you are calling may be acquiring/releasing locks behind the scenes. Win32 has a similar API: SuspendThread and ResumeThread. The following docs for SuspendThread give a nice summary of the dangers of the API:

http://msdn.microsoft.com/en-us/library/ms686345(VS.85).aspx

This function is primarily designed for use by debuggers. It is not intended to be used for thread synchronization. Calling SuspendThread on a thread that owns a synchronization object, such as a mutex or critical section, can lead to a deadlock if the calling thread tries to obtain a synchronization object owned by a suspended thread. To avoid this situation, a thread within an application that is not a debugger should signal the other thread to suspend itself. The target thread must be designed to watch for this signal and respond appropriately.

The proper way to suspend a thread indefinitely is to use a ManualResetEvent. The thread is most likely looping, performing some work. The easiest way to suspend the thread is to have the thread "check" the event each iteration, like so:

while (true)
{
_suspendEvent.WaitOne(Timeout.Infinite);

// Do some work...
}

You specify an infinite timeout so when the event is not signaled, the thread will block indefinitely, until the event is signaled at which point the thread will resume where it left off.

You would create the event like so:

ManualResetEvent _suspendEvent = new ManualResetEvent(true);

The true parameter tells the event to start out in the signaled state.

When you want to pause the thread, you do the following:

_suspendEvent.Reset();

And to resume the thread:

_suspendEvent.Set();

You can use a similar mechanism to signal the thread to exit and wait on both events, detecting which event was signaled.

Just for fun I'll provide a complete example:

public class Worker
{
ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
ManualResetEvent _pauseEvent = new ManualResetEvent(true);
Thread _thread;

public Worker() { }

public void Start()
{
_thread = new Thread(DoWork);
_thread.Start();
}

public void Pause()
{
_pauseEvent.Reset();
}

public void Resume()
{
_pauseEvent.Set();
}

public void Stop()
{
// Signal the shutdown event
_shutdownEvent.Set();

// Make sure to resume any paused threads
_pauseEvent.Set();

// Wait for the thread to exit
_thread.Join();
}

public void DoWork()
{
while (true)
{
_pauseEvent.WaitOne(Timeout.Infinite);

if (_shutdownEvent.WaitOne(0))
break;

// Do the work here..
}
}
}

How to indefinitely pause a thread in Java and later resume it?

Who said Java is not low level enough?

Here is my 3 minute solution. I hope it fits your needs.

import java.util.ArrayList;
import java.util.List;

public class ThreadScheduler {

private List<RoundRobinProcess> threadList
= new ArrayList<RoundRobinProcess>();

public ThreadScheduler(){
for (int i = 0 ; i < 100 ; i++){
threadList.add(new RoundRobinProcess());
new Thread(threadList.get(i)).start();
}
}

private class RoundRobinProcess implements Runnable{

private final Object lock = new Object();
private volatile boolean suspend = false , stopped = false;

@Override
public void run() {
while(!stopped){
while (!suspend){
// do work
}
synchronized (lock){
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
}
}

public void suspend(){
suspend = true;
}
public void stop(){
suspend = true;stopped = true;
synchronized (lock){
lock.notifyAll();
}
}

public void resume(){
suspend = false;
synchronized (lock){
lock.notifyAll();
}
}

}
}

Please note that "do work" should not be blocking.

Is there a way to pause a thread indefinitely in VB.Net

A short vb example

Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
thrd.IsBackground = True
thrd.Start()
End Sub

Dim thrd As New Threading.Thread(AddressOf somethread)

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'pause and resume
'first click pauses, second click resumes
reqpause.Set() 'set event
End Sub

Dim reqpause As New Threading.AutoResetEvent(False)

Private Sub somethread()
Do
'simulate work - your code here
Threading.Thread.Sleep(500)
Debug.WriteLine(DateTime.Now.ToLongTimeString)
'end simulate work

If reqpause.WaitOne(0) Then 'pause requested?
Debug.WriteLine("t-thrd paused")
reqpause.WaitOne() 'wait here for continuation
Debug.WriteLine("t-continue thrd")
End If
Loop
End Sub

how to pause/resume a thread

Maybe the ManualResetEvent is a good choice.
A short example:

private static EventWaitHandle waitHandle = new ManualResetEvent(initialState: true); 

// Main thread
public void OnPauseClick(...) {
waitHandle.Reset();
}

public void OnResumeClick(...) {
waitHandle.Set();
}

// Worker thread
public void DoSth() {
while (true) {
// show some random text in a label control (btw. you have to
// dispatch the action onto the main thread)
waitHandle.WaitOne(); // waits for the signal to be set
}
}

How to pause running thread and restart same thread when needed?

That's what a BlockingQueue exists for. It has a take() method that forces a thread to block until an Object is avalaible. Your problem can be solved with a simple producer-consumer design.

I'm pasting here a minimal snippet taken from the Oracle examples:

class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}

class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}

Of course Consumer an Producer have to share the queue somehow (just passing it to the constructor as shown in the example will work fine).

C# : How to pause the thread and continue when some event occur?

You could use a System.Threading.EventWaitHandle.

An EventWaitHandle blocks until it is signaled. In your case it will be signaled by the button click event.

private void MyThread()
{
// do some stuff

myWaitHandle.WaitOne(); // this will block until your button is clicked

// continue thread
}

You can signal your wait handle like this:

private void Button_Click(object sender, EventArgs e)
{
myWaitHandle.Set(); // this signals the wait handle and your other thread will continue
}

How can we make a thread to sleep for a infinite time in java?

I can't think of a good reason for doing this. As one of the comments noted Long.MAX_VALUE is roughly 292 billion years so probably Thread.sleep(Long.MAX_VALUE) is enough. But if you want a theoretical infinite sleep solution:

while (true) {
Thread.sleep(Long.MAX_VALUE);
}

Would looping Thread.Sleep() be bad for performance when used to pause a thread?

I think, based on the description, I'd do this

'Class level.
Private BytesWritten As Long = 0
Private NotPaused As New Threading.ManualResetEvent(True)

The change in the variable name is fitting since this is how it would be used

    'Method (thread) level.
While BytesWritten < [target file size]
'...write 4096 byte buffer to file...

NotPaused.WaitOne(-1)

'...do some more stuff...
End While

To make the loop pause do this

    NotPaused.Reset()

and to continue

    NotPaused.Set()

stop-pause-continue two synchronized threads

Finally i used logical flags following and older answer from @Roman
How to indefinitely pause a thread in Java and later resume it?



Related Topics



Leave a reply



Submit