How to pause/suspend a process?

W

Wim

My GUI application starts a process (a console program) when the user
hits Play. I would like to add an option to pause that process. The
code I've added to detect if the user hit pause/unpause seems to work.
But I have no clue how to pause/suspend the process. As far as I can
see the Process class doesn't offer anything for this. So it's probably
the thread the process is running on that should be suspended or put to
sleep. But just putting Thread.Suspend() on the place of the
questionmarks results in a compiling error (error CS0120: An object
reference is required for the nonstatic field, method, or property
'System.Threading.Thread.Suspend()'). So my question is: if I'm on the
right way how to get an object reference to the thread myProcess is
running on. Or else maybe some suggestions how to do it.

Relevant code:

private void menuPlay_Click(object sender, System.EventArgs e)
{
//(...)
MethodInvoker mi = new MethodInvoker(Execute);
mi.BeginInvoke(null, null);
}

private void Execute()
{
//(...)
myProcess.StartInfo.CreateNoWindow = true;
myProcess.Start();
while (! myProcess.HasExited)
{
Thread.Sleep(500);
if (PauseRequested == true)
{
//???
}
}
}

private bool IsPaused;

private void menuPause_Click(object sender, System.EventArgs e)
{
if (menuPause.Checked == true)
menuPause.Checked = false;
else
menuPause.Checked = true;

lock(this)
{
IsPaused = menuPause.Checked;
}
}

protected bool PauseRequested
{
get
{
lock(this)
{
return IsPaused;
}
}
}
 
G

Guest

Hi Wim,

Yes your are going in the right direction. You need to suspend the current thread. This can be done by

Thread.CurrentThread.Suspend();

When you need to continue you would call the resume method.

i.e. Thread.CurrentThread.Resume();

thanks
Nithin P V
 
W

Wim

Nithin said:
Yes your are going in the right direction. You need to suspend the
current thread. This can be done by

Thread.CurrentThread.Suspend();

When you need to continue you would call the resume method.

i.e. Thread.CurrentThread.Resume();

That would be great, but it doesn't work: the process doesn't pause
when I hit Pause.
 
B

Bruno Jouhier [MVP]

Nithin said:
Hi Wim,

Yes your are going in the right direction. You need to suspend the current thread. This can be done by

Thread.CurrentThread.Suspend();

When you need to continue you would call the resume method.

i.e. Thread.CurrentThread.Resume();

This part won't work. If the current thread is suspended, it won't be able
to execute the Resume method!!! A thread can only be resumed by another
thread.

Suspend and Resume are dangerous methods because you are likely to get
deadlocks if you suspend a thread that has acquired locks. IMO, it should be
reserved to special tools like debuggers and the likes.

Rather than use Suspend/Resume, I suggest that you investigate Wait / Pulse.
This is the right way to do synchronization.

Bruno.
 
W

Willy Denoyette [MVP]

You can't "pause" or "resume" another process, unless the other process
run's as a service.

Willy.
 
A

Arthur Mnev

Create Two major threads:

a) Control Thread (Thread A)
b) Worker Thread(Thread B) (anything multithrading you do thereafter
are spawned off by this thread

c) Create a ManualResetEvent, Mutex or anything that allows for thread
synchronization to occur.
pseudo code - Assumes you have an interface


Thread A - Create Control Form We will be running in, pause / run
button on the control form. Containing Start / Pause / Stop buttons

Thread A - Create a new Thread (Thread B)
Thread A - ManualResetEventObject.Reset()
Thread A - Start Thread B
Thread B - Start Execution of a worker function
[ Worker Function]
WaitOne(ManualResetEventObject);
Do the job



- Two methods here once graceful another one is dirty - dependes on
what you are doing. If you have to pause immideately - use dirty
method, however, if you are executing someting in a loop and you can
wait to complete current cycle - use graceful method.

When Thread A creates Thread B, thread B starts the function, but the
first statement of it is WaitOne(ManualResetEventObject). For the
thread to coninue it has to wait until ManualResetEventObject gets
into a signaled state. Until then it will sleep.

Hit Play Button, as an event for Play Button Thread A executes
ManualResetEvent.Set; as soon as it happens Thread B is awokes and
starts doing its work. If you need to pause, Hit stop button; during
which Thread A will call ManualResetEventObject.Reset(); Thread B will
continue execution until the time it gets to
WaitOne(ManualResetEventObject) statement, at which point (we are in
the same position as we were when we started thread B; it will fall
asleep until ManualResetEventObject will become signaled again.

This is for a nice graceful way. If you are not doing things in a loop
and have no way to inject ManualResetEventObject or need to thread to
suspend immedeately - Let Thread A call "Thread B.Suspend()" on pause,
and "Thread B.Resume()" on resume. When you will want to terminate
thread B.

A few notes Never, ever let Thread B have a higher priority then
Thread A - might have problems suspending things:)

Dont work with processes, use threads.

Disclaimer: for the past 8 months I was working with ASP.NET thus have
not had a chance to do a lot of multithreading :)- use above for what
its worth
 
W

Willy Denoyette [MVP]

Did you actually read OP's question? He want's to pause the OTHER process
(a console application, probably something not written by himself). This is
something you can't do (unless you are attaching a debugger to that
process).

Willy.
 
W

Wim

Willy Denoyette said:
Did you actually read OP's question? He want's to pause the OTHER
process (a console application, probably something not written by
himself). This is something you can't do (unless you are attaching a
debugger to that process).

Yes, you are right, that's exactly what I want to do. And I still
haven't figured it out. I don't see why it can't be done. With a
program like Process Explorer
(www.sysinternals.com/ntw2k/freeware/procexp.shtml) every process can
be suspended and resumed. Of course I can't program anywhere near as
good as the guys at Sysinternals, but why can't it be done from my
program?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top