Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: Threading .NET4 Process
Hi guys.
Recently I've encountered with problem of creation Process from dedicated thread.
Method which creates process look-like this
public static string ExecuteDcmtk(string exe, string args, string workingDir)
        {
            string result;
            Process p = new Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.FileName = exe;
            p.StartInfo.Arguments = args;
            p.StartInfo.WorkingDirectory = workingDir;
            p.Start();
            result = p.StandardOutput.ReadToEnd();
            p.WaitForExit();
            return result;
        }
 
In my thread i call this method and as a result caught next exception: System.Threading.ThreadAbortException
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
Who can help me with this issue?
thread propertie ISBackground is set to true.
Posted 11-Jun-12 2:51am
Comments
SAKryukov at 11-Jun-12 14:10pm
   
Where is the call to Thread.Abort in your code? In what thread do you have this exception?
--SA
Oleksandr Kulchytskyi at 11-Jun-12 15:46pm
   
I do not use Thread.Abort. This can corrupt workflow state.
I use CancellationtokenSource and IsCancelled property for monitoring whether cancellation is requested,
thread run in infinite loop and periodically , say one time in 5 minute must run process.
SAKryukov at 11-Jun-12 17:08pm
   
It won't corrupt anything if you use if with full understanding of how it works. Nevertheless, I don't believe there is such thing as the miracle: if you have ThreadAbortException, it means that Thread.Abort was called with the thread where you have this exception. If you did not do it, some library code you use might do it.
--SA
SAKryukov at 11-Jun-12 14:47pm
   
As I understand, the only reason to have a dedicated thread for this is WaitForExit. But this wait is only needed when this thread notifies some other thread asynchronously about the event of the termination of the child process, otherwise it should simply return without wait; and a separate thread would not be needed. So, why do you wait in a separate thread without doing anything about it?
--SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Please see my comments to the question. There must be a call to Thread.Abort somewhere. And your dedicate thread and the wait for the termination of the child process should have a reason, but this is not shown in your code.
 
Exceptions are not errors. (Important point many developers miss.) The exception System.Threading.ThreadAbortException is the very important exception used to process asynchronous Thread.Abort. It is used in the thread being aborted and allows this thread to exit correctly after abort, performing some post-mortal will of the thread, so it can finalize important object and perform other actions making abortion of the thread safe and correct. In many cases, this aspect of programming is not trivial.
 
Before explaining how it works, let me give you a word of warning. The method Thread.Abort is a very powerful method, and it is considered correct and safe, in contrast to deprecated Thread.Suspend because it is unsafe, and in contrast to Windows API TerminateThread, which is not even included in .NET API. Nevertheless, you should use this powerful method only if you perfectly understand how it works and what are the possible consequences. There is a class of application where the collaborative termination of the thread is impossible by the nature of the task, then this method is indispensable. If you are not 100% comfortable with this method, you should better use collaborative method: a thread simply exists its main method when the work is done. The other thread can instruct this thread to terminate by passing some request to is, which should be checked by the thread to be terminated periodically. Such cooperative termination is explained here:
http://msdn.microsoft.com/en-us/library/7a2f3ay4%28v=vs.90%29.aspx[^].
 
The method Thread.Abort uses exception seeding. Before .NET emerged, I saw an article from the Microsoft developer who demonstrated the technique on Windows API. Unfortunately, at this moment I don't have my literature references list to find out the original work. The code is platform-dependent, different for different Windows implementations for different instruction-set architectures, but it is based on documented Windows API. So, how to cause thread termination asynchronously to this thread? The thing is: the threads are scheduled by system scheduler; and their content is stored in the system memory. Windows API has documented access to this storage. So, a terminating thread can pause the thread to be terminated for a short time. The thread context is flashed to the system memory. Then the Instruction Pointer of suspended thread is modified to jump to some code. Of course, when the thread jumps instruction flow to some fixed code fragment, the thread's stack gets messed up. There is only one case when it does not matter. What case? When the fragment of code the thread jumps to never returns but throws exception instead. (To understand it, you should have good understanding on how exceptions work and what they do to the thread's stack.) And what is that exception? Right, this is that very ThreadAbortException. I actually implemented such mechanism, that's why I know the detail. This is how it all really works in .NET and other CLR implementations.
 
Now, being perfectly safe in principle, abortion of the thread is still unsafe in certain cases. One case is constructing some objects in the thread which can potentially be aborted. The behavior of the code aborted in the state when some objects are "half-constructed" is unpredictable. Everything has its work-around. You can simply avoid such unsafe operations in a thread which can be aborted, or you can protect it from abortion by avoiding direct abort. You can provide an indirect abort method (still to be called from a different thread) is a thread wrapper interlocked with the lock statement, with the possibility to deny or defer abortion in certain critical sections of the code.
 
[EDIT #1]
 
Important: In contrast to what would be expected based on common sense, the methods System.Threading.Thread.BeginCriticalRegion and System.Threading.Thread.EndCriticalRegion do not provide required protection from the cases I mentioned in the previous paragraph. According to the documentation, they only notify the host that "the effects of a thread abort or unhandled exception might jeopardize other tasks in the application domain". Please see:
 
http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx[^] (see BeginCriticalRegion),
http://msdn.microsoft.com/en-us/library/system.threading.thread.begincriticalregion.aspx[^].
 
You can create a period where the thread spend extended period of time in the critical region and try to abort it from another thread. It will be aborted!
 
[END EDIT #1]
 
[EDIT #2]
 
I also noticed that you use Thread.IsBackground = true; and would like to warn about it. Indeed, the thread marked as a background thread will be terminated automatically after the main thread of the application is terminated; and this is the main difference between a background and non-background thread. It looks convenient and can work, but in most situations it's less predictable the with Thread.Abort. There is no a way to terminate a thread at deterministic time, but with cooperative termination or with Thread.Abort, your can control the order of some of the operations and guarantee that, say, one thread is ready for termination of some other thread. If you leave it uncontrolled relying on the automatic termination of a background thread, order of operations is unpredictable. It still can be used in very simple situation of the end of application lifetime and order of operations and other affected detail is not important. Again, you can only do it if you clearly understand how it works and affects your application termination.
 
[END EDIT #2]
 
[EDIT #3]
 
Please see also my past answer on related topic:
Close correcly the thread inside a dll[^].
 
[END EDIT #3]
 
I did not provide detail of the mechanisms of such advanced method of thread termination and safety measures because I'm not sure you need them. If interested, you are welcome to ask further questions.
 
—SA
  Permalink  
v11
Comments
Oleksandr Kulchytskyi at 11-Jun-12 15:48pm
   
My 5 to your answer , As always, you are giving a very informative answers and advices. Codeproject must proud , that have such experienced people like you !
SAKryukov at 11-Jun-12 17:05pm
   
You are welcome, and thank you for your nice words.
If you like it so much, will you accept the answer formally (green button)?
By the way, it won't prevent you from accepting another one.
Thank you.
--SA
losmac at 11-Jun-12 17:49pm
   
I have no words... only WOW!
BIG 5!
SAKryukov at 11-Jun-12 18:00pm
   
Thank you very much, Maciej.
By the way, I added important detail I learned in last year, another word of caution; after [EDIT].
--SA
Prasad_Kulkarni at 12-Jun-12 0:28am
   
Simply great! Hats off to your answer SA.
5 is really less for such informative answer..
SAKryukov at 12-Jun-12 0:49am
   
Thank you very much, Prasad.
--SA
Espen Harlinn at 12-Jun-12 14:10pm
   
Nice reply!
 
Going from 300K to 400K in no time, or nearly - well I'm impressed :-D
SAKryukov at 12-Jun-12 15:07pm
   
Thank you very much, Espen.
I'm trying to keep up without compromising quality and my main work.
--SA
Espen Harlinn at 12-Jun-12 15:18pm
   
As I said, impressive - currently working on a gas flare risk evaluation tool and working my a$$ off > 70 hours a week; and while this is work I would normally enjoy, I'm getting more than a bit miffed (and tired ...)
SAKryukov at 13-Jun-12 12:25pm
   
Even though things are very individual here, I'm sure this rate cannot pay off, except very limited periods of time. 40 h/week makes certain sense.
--SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

I found and resolved issue. In my question i didnt notice, that this exception occurred in my TestMethod in Unit test project
The problem has been buried in Visual Studio Unit test settings.
Thread abort exception was thrown by Visual Studio, as i noticed in my thread is run in infinite loop and periodically one time in 10 - 20 sec run process. For waiting ability i use Thread.Sleep method. After some period of time, let's say , after 2 minutes, in debug mode when VS steps to Sleep method , it waits , and than process begin to hungs up and after that throws ThreadAbortException.
When i set in VS project setting visual studio hosting property to true,
my this issue didnt repeat.
But thanks you all for informative answers =)
  Permalink  
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 400
1 Sergey Alexandrovich Kryukov 329
2 Afzaal Ahmad Zeeshan 264
3 BillWoodruff 245
4 CPallini 195
0 OriginalGriff 5,560
1 DamithSL 4,476
2 Maciej Los 3,942
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,175


Advertise | Privacy | Mobile
Web02 | 2.8.141216.1 | Last Updated 12 Jun 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100