C# 其中一个线程阻止.NET程序完全停止。如何识别哪一个?
我有一个具有很多功能的大型应用程序。有时,当您关闭主窗体时,它会顺利退出。其他时候窗体关闭,但程序仍在运行。VisualStudio2010提供了哪些调试工具来识别行为异常的线程 在所有具有C# 其中一个线程阻止.NET程序完全停止。如何识别哪一个?,c#,.net,multithreading,visual-studio-2010,C#,.net,Multithreading,Visual Studio 2010,我有一个具有很多功能的大型应用程序。有时,当您关闭主窗体时,它会顺利退出。其他时候窗体关闭,但程序仍在运行。VisualStudio2010提供了哪些调试工具来识别行为异常的线程 在所有具有IsBackground==false的线程完成之前,应用程序将不会退出 连接VS调试器时,可以使用Threads窗口查看哪些线程仍在运行 VS菜单:调试->窗口->线程。如果它有时平稳关闭,而不是在其他时间关闭。。我想看看你是如何释放或释放对象和/或退出应用程序的。。你有没有任何代码,例如,它会读什么 En
IsBackground==false
的线程完成之前,应用程序将不会退出
连接VS调试器时,可以使用Threads
窗口查看哪些线程仍在运行
VS菜单:调试->窗口->线程。如果它有时平稳关闭,而不是在其他时间关闭。。我想看看你是如何释放或释放对象和/或退出应用程序的。。你有没有任何代码,例如,它会读什么
Environment.Exit(0); for example..?
您可以循环所有打开的线程并关闭它们 通过以下方式实现: Process.GetCurrentProcess()线程 另一种选择是终止该过程:
Process.GetCurrentProcess().Kill() 最近我意识到,您还可以使用调试位置工具栏来监视正在运行的线程。当您想查看线程当前正在执行的特定方法/操作时,这也非常方便 为了便于识别,您可能需要设置
线程
对象的名称
属性。我通常使用this
作为前缀,后面是线程调用的方法
var thread = new Thread(...) { Name = this + ".Connect" };
我编写了以下代码来跟踪我创建的线程,并在退出时警告我是否有任何线程没有关闭 它可以完美地工作,并且具有在VisualStudio调试器中命名线程的优点,这使得调试更容易 要使用它,请对手动创建的每个线程调用以下命令:
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;
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
命名空间MyShared.MyHelper
{
///
///线程的助手类。
///
公共静态类读取
{
///
///记住一个线程,直到关机。
///关闭时,我们可以再次检查我们创建的所有线程是否都已关闭。
///
///我们希望在关机前记住的线程。
///线程的新名称。
公共静态void mymemberthreaduntillshutdown(此线程线程,字符串newName)
{
//检查线程之前是否已命名
//以避免可能的无效操作异常。
if(thread.Name==null)
{
thread.Name=“MyThread”+newName;
}
其他的
{
Write(“错误E20120118-1914。无法将线程重命名为\“{0}\”,因为它的名称已经是\“{1}\”\n”,
newName,thread.Name);
}
ThreadList[newName]=线程;
}
///
///这将存储在整个系统中运行的所有线程的列表。
///
私有静态只读字典ThreadList=新字典();
///
///在程序退出时,检查我们启动的所有线程是否都已退出。
///
公共静态bool OnShutdownCheckThreadsForExit()
{
如果(ThreadList.Count!=0)
{
foreach(线程列表中的var线程)
{
if(thread.Value.IsAlive)
{
Write(“错误E20120119-8152。线程名\“{0}\”在退出时未正确关闭。\n”,Thread.Key);
}
}
返回false;
}
其他的
{
返回true;
}
}
}
}
调试器。调试+全部中断。调试+Windows+线程。你能在关闭的地方发布代码吗。。您是否也在使用vs2010。。?如果是这样,请使用随附的调试器..您可以在主窗体关闭后中断程序的执行(请参阅“全部中断”按钮),并在“线程”窗口(调试->窗口->线程)中查看哪些线程仍处于活动状态。但我认为你的问题超出了Stackoverflow的范围。重复?如果应用程序的任何线程请求操作系统终止进程,应用程序将退出。操作系统不关心“IsBackground”或任何线程状态。除非有需要刷新的文件、需要提交的事务等,为什么不直接终止流程呢?应用程序在预期关闭时仍保持打开状态这一事实很可能表明代码中的某个错误/问题。如果您希望完全关闭,但没有得到它,则终止进程将治疗症状,但无法治愈疾病。终止线程是一个可怕的想法,通常会导致比解决问题更多的问题。请参阅,以了解不应依赖于线程.Abort
的原因。