Thread.Abort() and Process class

A

andrew

Hi,

I have the following issue with the Thread.Abort():

The main thread creates a worker thread which waits on a process
termination.

void ThreadProc()
{
Process proc = proc.Start("notepad.exe");
...
proc.WaitForExit();
}

// main thread
Thread th = new Thread(new ThreadStart(ThreadProc));
th.Abort();

The Abort() call from the main thread does not work as expected, to throw
ThreadAbort exception within the thread immediately. Instead it does throw
it after the WaitForExit() call returns.

I tried to search on internet for Thread.Abort() issues and I found a desc
by Chris Sells about the inner workings of Abort() and the fact that it uses
an APC to issue the exception within the thread.

The problem is, if that is true, then I think that WaitForExit() is doing a
non-alertable waiting, its behaviour would explain it.
If thats the case then the MSDN should say that.
But, what i tried was to replace the Process.WaitForExit() call with a
pinvoke call on the WaitForSingleObjectEx with alertable flag set to 1:

void ThreadProc()
{
Process proc;
...
WaitForSingleObjectEx(proc.Handle, -1, 1); // -1 is INFINITE wait value
and 1 is to make the wait alertable
}

this did not work either. the Abort() call does not throw the exception.

can anyone please explain this ?


My second problem relates to the Process.WaitForExit().
I've just had a situation where the process exited but the call does not
return !
The strange thing was that the proc variable had HasExited property
returning true.
So my question is, how reliable is the Process.WaitForExit() ?
I expected that the wait to be close to the complexity and value of the
simple native call of the WaitForSingleObjectEx (or close to).

After all these, I dont feel confident in the way that Process and
Thread.Abort class work.
 
N

Nicholas Paldino [.NET/C# MVP]

The reason that the call to Abort does not work is because the call to
WaitForExit is making a call through the P/Invoke layer. Any calls on a
thread through the P/Invoke layer or through COM interop can not be aborted
with a call to Abort until the interop call completes.
 
A

andrew

I see, but this is bad then.
if you do an Abort() and then a Join(), the calling threads remains blocked
due to whats inside the thread proc.
Then the documentation should say that, as its is very important !
Why is that anyway, can you please explain a bit ? or you can point to a
place where this is discussed.

what about the fact that

thanks.

Nicholas Paldino said:
The reason that the call to Abort does not work is because the call to
WaitForExit is making a call through the P/Invoke layer. Any calls on a
thread through the P/Invoke layer or through COM interop can not be
aborted with a call to Abort until the interop call completes.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

andrew said:
Hi,

I have the following issue with the Thread.Abort():

The main thread creates a worker thread which waits on a process
termination.

void ThreadProc()
{
Process proc = proc.Start("notepad.exe");
...
proc.WaitForExit();
}

// main thread
Thread th = new Thread(new ThreadStart(ThreadProc));
th.Abort();

The Abort() call from the main thread does not work as expected, to throw
ThreadAbort exception within the thread immediately. Instead it does
throw it after the WaitForExit() call returns.

I tried to search on internet for Thread.Abort() issues and I found a
desc by Chris Sells about the inner workings of Abort() and the fact that
it uses an APC to issue the exception within the thread.

The problem is, if that is true, then I think that WaitForExit() is doing
a non-alertable waiting, its behaviour would explain it.
If thats the case then the MSDN should say that.
But, what i tried was to replace the Process.WaitForExit() call with a
pinvoke call on the WaitForSingleObjectEx with alertable flag set to 1:

void ThreadProc()
{
Process proc;
...
WaitForSingleObjectEx(proc.Handle, -1, 1); // -1 is INFINITE wait
value and 1 is to make the wait alertable
}

this did not work either. the Abort() call does not throw the exception.

can anyone please explain this ?


My second problem relates to the Process.WaitForExit().
I've just had a situation where the process exited but the call does not
return !
The strange thing was that the proc variable had HasExited property
returning true.
So my question is, how reliable is the Process.WaitForExit() ?
I expected that the wait to be close to the complexity and value of the
simple native call of the WaitForSingleObjectEx (or close to).

After all these, I dont feel confident in the way that Process and
Thread.Abort class work.
 
N

Nicholas Paldino [.NET/C# MVP]

Andrew,

Personally, I think you are going about stopping the task the wrong way.
As a general rule, you shouldn't be using Join as a synchronization
primitive. I also don't believe you should be using Abort to stop the
process. Rather, you should be calling Kill on the process instance to stop
the process. The thread would then stop naturally after the process was
killed. You should then have an event that you set the handle on after the
call to WaitToExit, which you are waiting on in another thread.

As for the documentation about calling Abort on a thread in the middle
of an interop call, here you go:

http://msdn2.microsoft.com/en-us/library/74169f59.aspx

Specifically, look at the section titled "Blocking Issues".


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

andrew said:
I see, but this is bad then.
if you do an Abort() and then a Join(), the calling threads remains
blocked due to whats inside the thread proc.
Then the documentation should say that, as its is very important !
Why is that anyway, can you please explain a bit ? or you can point to a
place where this is discussed.

what about the fact that

thanks.

Nicholas Paldino said:
The reason that the call to Abort does not work is because the call to
WaitForExit is making a call through the P/Invoke layer. Any calls on a
thread through the P/Invoke layer or through COM interop can not be
aborted with a call to Abort until the interop call completes.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

andrew said:
Hi,

I have the following issue with the Thread.Abort():

The main thread creates a worker thread which waits on a process
termination.

void ThreadProc()
{
Process proc = proc.Start("notepad.exe");
...
proc.WaitForExit();
}

// main thread
Thread th = new Thread(new ThreadStart(ThreadProc));
th.Abort();

The Abort() call from the main thread does not work as expected, to
throw ThreadAbort exception within the thread immediately. Instead it
does throw it after the WaitForExit() call returns.

I tried to search on internet for Thread.Abort() issues and I found a
desc by Chris Sells about the inner workings of Abort() and the fact
that it uses an APC to issue the exception within the thread.

The problem is, if that is true, then I think that WaitForExit() is
doing a non-alertable waiting, its behaviour would explain it.
If thats the case then the MSDN should say that.
But, what i tried was to replace the Process.WaitForExit() call with a
pinvoke call on the WaitForSingleObjectEx with alertable flag set to 1:

void ThreadProc()
{
Process proc;
...
WaitForSingleObjectEx(proc.Handle, -1, 1); // -1 is INFINITE wait
value and 1 is to make the wait alertable
}

this did not work either. the Abort() call does not throw the exception.

can anyone please explain this ?


My second problem relates to the Process.WaitForExit().
I've just had a situation where the process exited but the call does not
return !
The strange thing was that the proc variable had HasExited property
returning true.
So my question is, how reliable is the Process.WaitForExit() ?
I expected that the wait to be close to the complexity and value of the
simple native call of the WaitForSingleObjectEx (or close to).

After all these, I dont feel confident in the way that Process and
Thread.Abort class work.
 
A

andrew

let me clear this up a little.
I am using AIAB (Asynchronous Invocation Application Block)
The caller thread which calls Abort() is the AIAB's SAMonitor thread
(monitoring the agent's worker threads).
it calls Abort() and then Join() on a worker thread which runs a service
agent implementation.

The problem is that in my service agent implemenation, I am spawning
processes and wait for their exit.
If in the meantime the AIAB's SAMonitor decides that my service agent thread
timedout, it calls like i said Abort and Join on it.

I didnt like this idea from the start. I guess this timeout sitation should
never appear on a service agent, but practice says it can and the AIAB's
Abort() solution is not kind at all.

So as you see I dont have much choice.
One option would be to have a separate thread running the service agent
code, catch the ThreadABort exception on the worker thread and stop my
thread in a proper way.
But this seems like I the overhead of creating separate threads for each
service agent execution.

any ideas?

thanks.


Nicholas Paldino said:
Andrew,

Personally, I think you are going about stopping the task the wrong
way. As a general rule, you shouldn't be using Join as a synchronization
primitive. I also don't believe you should be using Abort to stop the
process. Rather, you should be calling Kill on the process instance to
stop the process. The thread would then stop naturally after the process
was killed. You should then have an event that you set the handle on
after the call to WaitToExit, which you are waiting on in another thread.

As for the documentation about calling Abort on a thread in the middle
of an interop call, here you go:

http://msdn2.microsoft.com/en-us/library/74169f59.aspx

Specifically, look at the section titled "Blocking Issues".


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

andrew said:
I see, but this is bad then.
if you do an Abort() and then a Join(), the calling threads remains
blocked due to whats inside the thread proc.
Then the documentation should say that, as its is very important !
Why is that anyway, can you please explain a bit ? or you can point to a
place where this is discussed.

what about the fact that

thanks.

Nicholas Paldino said:
The reason that the call to Abort does not work is because the call
to WaitForExit is making a call through the P/Invoke layer. Any calls
on a thread through the P/Invoke layer or through COM interop can not be
aborted with a call to Abort until the interop call completes.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hi,

I have the following issue with the Thread.Abort():

The main thread creates a worker thread which waits on a process
termination.

void ThreadProc()
{
Process proc = proc.Start("notepad.exe");
...
proc.WaitForExit();
}

// main thread
Thread th = new Thread(new ThreadStart(ThreadProc));
th.Abort();

The Abort() call from the main thread does not work as expected, to
throw ThreadAbort exception within the thread immediately. Instead it
does throw it after the WaitForExit() call returns.

I tried to search on internet for Thread.Abort() issues and I found a
desc by Chris Sells about the inner workings of Abort() and the fact
that it uses an APC to issue the exception within the thread.

The problem is, if that is true, then I think that WaitForExit() is
doing a non-alertable waiting, its behaviour would explain it.
If thats the case then the MSDN should say that.
But, what i tried was to replace the Process.WaitForExit() call with a
pinvoke call on the WaitForSingleObjectEx with alertable flag set to 1:

void ThreadProc()
{
Process proc;
...
WaitForSingleObjectEx(proc.Handle, -1, 1); // -1 is INFINITE wait
value and 1 is to make the wait alertable
}

this did not work either. the Abort() call does not throw the
exception.

can anyone please explain this ?


My second problem relates to the Process.WaitForExit().
I've just had a situation where the process exited but the call does
not return !
The strange thing was that the proc variable had HasExited property
returning true.
So my question is, how reliable is the Process.WaitForExit() ?
I expected that the wait to be close to the complexity and value of the
simple native call of the WaitForSingleObjectEx (or close to).

After all these, I dont feel confident in the way that Process and
Thread.Abort class work.
 
P

Peter Duniho

Personally, I think you are going about stopping the task the wrong
way.
As a general rule, you shouldn't be using Join as a synchronization
primitive. I also don't believe you should be using Abort to stop the
process. Rather, you should be calling Kill on the process instance to
stop
the process.

In addition to what Nicholas already wrote, I'll suggest that it's a very
bad idea to kill processes anyway. Depending on the situation, this may
be unavoidable, but if there is _any_ other mechanism by which you could
close the process cleanly, that would be much better.

Pete
 
P

Peter Duniho

I don't kill any process. Please read my last post.

I understand. I was responding to Nicholas' suggestion that you _do_ kill
the process.

Maybe I should have phrased it better, but my point was that while most of
what Nicholas wrote is applicable, IMHO suggesting that you kill the
process isn't the right thing to do.
 
B

Brenda Hinkemeyer

I ran into a similar problem with WaitForExit() not returning. I found a little note on msdn that said the EnableRaisingEvents needed to be set to true whether you do the event handloer OR use WaitForExit. Try setting that to true.
 

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