C#挂起所有线程

前端之家收集整理的这篇文章主要介绍了C#挂起所有线程前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个可能相当独特的问题.我有一个应用程序,当我不在场时长时间在无头盒子上运行,但并不重要.我希望能够使用Visual Studio远程调试此应用程序.为此,我的代码如下所示:
// Suspend all other threads to prevent loss
// of state while we investigate the issue.
SuspendAllButCurrentThread();
var remoteDebuggerProcess = new Process
    {
        StartInfo =
            {
                UseShellExecute = true,FileName = MsVsMonPath;
            }
    };
// Exception handling and early return removed here for brevity.
remoteDebuggerProcess.Start();

// Wait for a debugger attach.
while (!Debugger.IsAttached)
{
    Thread.Sleep(500);
}
Debugger.Break();

// Once we get here,we've hit continue in the debugger. Restore all of our threads,// then get rid of the remote debugging tools.
ResumeAllButCurrentThread();

remoteDebuggerProcess.CloseMainWindow();
remoteDebuggerProcess.WaitForExit();

这个想法就是这样,当我离开的时候,我遇到了一个错误,并且应用程序有效地暂停了自己并等待远程调试器连接,在第一次继续之后,由于Debugger.Break调用,它会自动获得正确的上下文.

问题在于:实现SuspendAllButCurrentThread是非常重要的.不推荐使用Thread.Suspend,我不能P / Invoke到SuspendThread,因为托管线程和本机线程之间没有一对一的映射(因为我需要保持当前线程处于活动状态).如果可以避免,我不想在有问题的机器上安装Visual Studio.我怎样才能做到这一点?

解决方法

I can’t P/Invoke down to SuspendThread because there’s no one-to-one mapping between managed threads and native threads

您也不能枚举托管线程,只能枚举非托管线程.实际上它们之间存在一对一的映射,它们只是很难找到它.最初的目的是允许创建一个不使用操作系统线程来实现Thread的自定义CLR主机,这是sql Server组要求使用光纤的请求.从来没有成功,他们无法让它足够可靠.不存在不使用实际操作系统线程的实际CLR主机.

所以你实际上可以使用Process.GetCurrentProcess().线程来枚举你所有的线程.并避免通过pinvoking GetCurrentThreadId()暂停您自己的,将它与ProcessThread.Id进行比较

这样做的可靠性是一种猜测,不要试图做任何激烈的事情,如发送警报提醒您是时候连接调试器了.您可能已经暂停了在Windows中执行代码并获得全局锁定的线程.以及CLR工作线程,如终结器线程或后台GC线程.

更好的方法是使用一个单独的保护进程来完成所有这些,就像调试器一样.使用您在后台程序中创建的命名EventWaitHandle和主程序中的OpenExisting().保护程序需要等待句柄以及进程的WaitAny().你的主程序现在可以简单地调用Set()来唤醒守卫程序.现在可以安全地暂停所有线程.

原文链接:https://www.f2er.com/csharp/244608.html

猜你在找的C#相关文章