Один из потоков предотвращает полную остановку программы .NET.Как определить, какой? - PullRequest
6 голосов
/ 26 декабря 2011

У меня большое приложение с множеством функций. Иногда, когда вы закрываете основную форму - она ​​выходит плавно. В других случаях форма закрывается, но программа продолжает работать. Какие средства отладки Visual Studio 2010 предоставляет для выявления неправильно работающих потоков?

Ответы [ 5 ]

1 голос
/ 24 января 2012

Я написал следующий код, чтобы отслеживать, какие потоки я создал, и предупреждать меня, если какой-либо из них не был закрыт, при выходе.

Он работает безупречно и имеет преимущество в именовании потоков в отладчике Visual Studio, что облегчает отладку.

Чтобы использовать его, вызовите следующее для каждого потока, созданного вами вручную:

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

Затем вызовите следующее при выходе:

OnShutdownCheckThreadsForExit();

Вот класс помощников:

    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;
                }
            }
        }
    }
1 голос
/ 26 декабря 2011

Ваше приложение не будет закрыто, пока не завершатся все потоки с IsBackground == false.

Вы можете использовать окно Threads, когда отладчик VS подключен, чтобы увидеть, какие потоки все еще работают.

VS Меню: Отладка -> Windows -> Потоки.

0 голосов
/ 26 декабря 2011

Недавно я понял, что вы также можете использовать панель инструментов Отладка для наблюдения за запущенными потоками.Это также очень удобно, когда вы хотите увидеть, какой конкретный метод / операцию выполняет поток в настоящее время.

Для упрощения идентификации вы можете установить свойство Name вашего объекта Thread.В основном я использую this в качестве префикса, а затем метод, вызываемый потоком.

 var thread = new Thread(...) { Name = this + ".Connect" };
0 голосов
/ 26 декабря 2011

Вы можете перебрать все открытые потоки и закрыть их.

Сделать это можно следующим образом: Process.GetCurrentProcess (). Threads

Другой альтернативой будет прекращение процесса:

Process.GetCurrentProcess () убивать ();.

0 голосов
/ 26 декабря 2011

Если оно закрывается иногда плавно, а не в другое время ... Я бы посмотрел, как вы освобождаете или отпускаете объекты и / или выходите из приложения ... У вас есть какой-нибудь код, например, где он будет читать

Environment.Exit(0); for example..?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...