HI,
I have a .NET application which uses threads excessively. At the time of exit the process does not kill itself. Is there is any tool that can show what is causing the problem? although I have checked thoroughly but was unable to find the problem.
Abdul Khaliq
See: Why doesn't my process terminate even after main thread terminated
That means you have some foreground thread running. A .net application will not terminate unless all the foreground threads complete execution.
You can mark threads as Background Threads and then check (Thread.IsBackground property). Please note that all background threads terminate immediately when application exits. If you are doing some important work in those threads like serializing data to database then you should keep them as foreground threads only. Background threads are good for non critical things like spell cheker etc.
Normally, attaching with a debugger should tell you what threads are still active and what code is running on them.
Related
I converted our application from C# on Windows to .Net Core running on Linux with Ryder IDE framework.
Our app uses several third-party frameworks such as ServiceStack, RabbitMq and Mailkit libraries.
When I open the Debug Output window I see that the system is starting and stopping threads at the rate of over 10 a second.
Started Thread 18213
Exited Thread 18213
Started Thread 18214
Exited Thread 18214
Started Thread 18215
Exited Thread 18215
Started Thread 18216
Exited Thread 18216
Started Thread 18217
Exited Thread 18217
Started Thread 18218
As there are 100's of classes I have no idea where to start to see which method is started and stopping threads at this rate.
How can I track this down?
Is there a method that I could overload on the thread pool that would allow us to set a breakpoint when these threads start and stop.
I've attempted to enable settings > Build, Execution > Debugger > Process exceptions outside of my code And I see a lot of exceptions being thrown in the RabbitMQ library, but I have no idea if this relates to the Thread cycling issue.
I enabled the System.Treading.ThreadStartExcepton and it wasn't hit.
Any help would be appreciated.
Welcome to thread pool .Net Core and async-await in general.
What is the problem do you have for here?
Those outputs Started Thread and Exited Thread are not bugs in your code it's by design of Asp.Net Core framework
A thread pool is a pool of worker threads that is available on demand
as needed. The code examples in this article show how to use the
thread pool in .NET Core using C#.
Unfortunately there's no mechanism for tracking what is starting or stopping threads in a .NET application. If you examine a thread in a debugger, you can see the call-stack of the thread, including (at the base of the stack) the method which was called to start the thread doing work. This might give you some information as to what the thread was supposed to be doing.
The reality is that if it's not your code, you probably can't do much about how these threads are being managed. It's likely you're seeing the normal behaviour of the .NET thread pool. Unless you're seeing a problem with a large number of threads or very high thread turnover, best to not pull this thread.
I'll start by saying I do not have a lot of experience in troubleshooting multi-threading problems. So a lot of what I've read about debugging race conditions, dead locks, live locks, etc. are strictly theoretical to me.
I have this .NET application that is making use of a dynamically loaded native win32 dll. If the dll is never loaded the application terminates without a problem. However, if the dll is loaded then when the user exits the application the UI disappears but the process never terminates.
I've turned on native code debugging in the project settings so I can see all the threads that are running. When the user closes the application window the main thread appears to terminate. I know this because if I perform a Break All in the Threads windows in Visual Studio the main thread is re-categorized as a worker thread and there is no call stack available for it. There are 20 other threads still active, all with call stacks. I've looked through the call stacks for all of these threads and nothing sticks out at me (there's no mention of the dll in any of the call stacks).
What steps can I take to narrow down the cause of this problem? Are there any additional tools I should be using to help pin point the problem?
This means that some of your Foreground Threads are still alive. Unlike Background Threads, Foreground Threads keeps the process alive.
You should either use Background Threads or Stop your Foregrounds Threads to be able to exit the process gracefully.
Windows application will automatically exit when all of its thread(s) are stopped.
As you said
If the dll is never loaded the application terminates without a
problem
I'm assuming all the running threads are unmanaged threads(not created by clr). There is no concept of background threads in native code. All threads must be terminated to terminate the process.
You must find a way to signal all threads to exit in that library. See if you have any api exposed for that.
If you don't find anything, you've got a "Sledge Hammer" approach. i.e Terminate the process with Environment.Exit which works almost always. Be sure you use this approach as a last resort as this can corrupt the process state.
My application starts multiple long-running functions/methods on their own threads. When one of these threads encounters an error, my program crashes (as expected). My question, though, is do all the threads spawned by the application stop executing? or do they hang around somewhere? If so, do I need to write another application to monitor them so I can kill them?
Thank you!
When a process finishes all threads contained in that process are terminated. A thread cannot exist outside of a process. Application crash = process termination.
If you are spawning processes from threads the processes you spawn will continue to run after the spawning process ends. You can kill the process tree in task manager and in code, but by default the spawned processes will keep running if your application ends ungracefully.
I'm assuming this is what you mean when you said
My application starts multiple long-running processes on their own threads
But maybe I'm misunderstanding what you are meaning to say
If the process which created all threads is killed/aborted, threads are aborted by the OS automatically. In other words: running process = at least one running thread, killed process = all threads terminated.
I've been searching through google a little bit and quite fast discovered that there are no solution on aborting a thread which is using COM Interop and is in a "wait for interop event" state. The Thread.Abort() will just put the thread into "AbortRequested" mode, which, quite franky, isn't much.
The results is me not being able to close my application. The process remains in the taskman because of the a childThread.
Anyone know if it is possible to Force Abort a thread?
Have you tried setting "IsBackground=True" on the thread? Threads marked as background will be cleaned up when the process is exiting, whereas process exit will wait for "foreground" threads.
We have a WinForms desktop application, which is heavily multithreaded. 3 threads run with Application.Run and a bunch of other background worker threads. Getting all the threads to shut down properly was kind of tricky, but I thought I finally got it right.
But when we actually deployed the application, users started experiencing the application not exiting. There's a System.Threading.Mutex to prevent them from running the app multiple times, so they have to go into task manager and kill the old one before they can run it again.
Every thread gets a Thread.Join before the main thread exits, and I added logging to each thread I spawn. According to the log, every single thread that starts also exits, and the main thread also exits. Even stranger, running SysInternals ProcessExplorer show all the threads disappear when the application exits. As in, there are 0 threads (managed or unmanaged), but the process is still running.
I can't reproduce this on any developers computers or our test environment, and so far I've only seen it happen on Windows XP (not Vista or Windows 7 or any Windows Server). How can a process keep running with 0 threads?
Edit:
Here's a bit more detail. One of event loops is hosting an Win32 interop DLL which uses a COM object to talk to a device driver. I put it in its own thread because the device driver is time sensitive, and whenever the UI thread would block for a significant amount of time (such as waiting for a database call to finish), it would interfere with the device driver.
So I changed the code so the main thread would do a Thread.Join with the device driver thread. That actually caused the application to lock up... it logs a few more calls on the UI thread after the Join completed and then everything stops. If the device is powered off, the driver never starts, and the problem goes away. So it looks like the driver must be responsible for keeping the application alive, even after it's supposedly been shut down.
When you create your threads, set IsBackground=true on them. When your main ui thread/app is closed, all created threads will automatically be shut down.
http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx
Is it possible that the children of your Application.Run calls aren't terminating? Also, what's actually causing the application to exit - does it automatically close when all the threads have terminated (automatically meaning you wrote some code to do that), or is it user-imitated?
I had an issue once where there was a race condition in my "thread complete" event code that would sometimes result in what you're seeing. The last two threads would finish at the same time, fire the event simultaneously, and each event would decide it wasn't the last thread, so the application would continue running, even though the thread count was zero. To resolve this, I was able to find and eliminate the race condition, but you could also use a timer that checks every second or two, gets a count of the threads, and if none are still open, it kills the application.
We never did figure out the root programmatic cause, but it was a specific driver version that caused the issue, and upgrading to a new driver fixed the problem.
Unfortunately, this is all the answer I can give, if someone else someday runs into a similar problem...