Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One of threads prevents .NET program from stopping completely. How to identify which one?

I have a large application with lots of functions. Sometimes, when you close the main form - it exits smoothly. Other times the form closes, but the program remains running. Which debugging tools does Visual Studio 2010 provide for identifying misbehaving threads?

like image 224
SharpAffair Avatar asked Dec 26 '11 12:12

SharpAffair


People also ask

How do I stop all running threads in C#?

foreach (Form form in Application. OpenForms) { form. Close(); } Application. Exit();

What happens to a thread when it finishes C#?

Short Answer: When a thread has finished its process, if nothing else holds a reference to it, the garbage collector will dispose of it automatically.

How do you stop a blocked thread?

Launch a seperate thread to perform the blocking call, and terminate() it if you need to stop the thread. You can use the IOU mechanism of Threads.


2 Answers

Your application will not exit until all threads that have IsBackground == false have finished.

You can use the Threads window when the VS debugger is attached to see which threads are still running.

VS Menu: Debug -> Windows -> Threads.

like image 100
Nick Butler Avatar answered Oct 15 '22 02:10

Nick Butler


I wrote the following code to keep track of which threads I have created, and warn me if any of them havn't shut down, on exit.

It works flawlessly, and it has the advantage of naming the threads within the Visual Studio debugger, which makes things easier to debug.

To use it, call the following on every thread that you create manually:

Thread x; 
// Yada yada create the thread. 
// Make sure you set ".IsBackground" property to "true".
x.MyRememberThreadUntilShutdown("name which is visible in VS debugger");

Then, call the following on exit:

OnShutdownCheckThreadsForExit();

Here is the helper class:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;

    namespace MyShared.MyHelper
    {
        /// <summary>
        /// Helper classes for threads.
        /// </summary>
        public static class MyThread
        {
            /// <summary>
            /// Remembers a thread, until shutdown.
            /// On shutdown, we can double check that all of the threads we created have been shut down.
            /// </summary>
            /// <param name="thread">Thread we want to remember until shutdown.</param>
            /// <param name="newName">New name for thread.</param>
            public static void MyRememberThreadUntilShutdown(this Thread thread, string newName)
            {
                // Check whether the thread has previously been named
                // to avoid a possible InvalidOperationException.
                if (thread.Name == null)
                {
                    thread.Name = "MyThread" + newName;
                }
                else
                {
                    Console.Write("Error E20120118-1914. Unable to rename thread to \"{0}\" as it already has a name of \"{1}\".\n",
                        newName, thread.Name);
                }

                ThreadList[newName] = thread;
            }

            /// <summary>
            /// This stores a list of all the threads we have running in the entire system.
            /// </summary>
            private static readonly Dictionary<string, Thread> ThreadList = new Dictionary<string, Thread>(); 

            /// <summary>
            /// On program exit, check that all of the threads we started have been exited.
            /// </summary>
            public static bool OnShutdownCheckThreadsForExit()
            {
                if (ThreadList.Count != 0)
                {
                    foreach (var thread in ThreadList)
                    {
                        if (thread.Value.IsAlive)
                        {
                            Console.Write("Error E20120119-8152. Thread name \"{0}\" was not shut down properly on exit.\n",thread.Key);
                        }
                    }
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }
    }
like image 21
Contango Avatar answered Oct 15 '22 02:10

Contango