进程线程(或整个进程)是否被挂起

时间:2013-08-16 07:40:26

标签: c# multithreading process

我想检查进程的线程(整个进程)是否被挂起。 我通过以下代码获取每个进程线程:

var threads = Proc.Threads;
for (int x = 0; x < threads.Count; x++) {
var thread = threads[x];

System.Diagnostics.ThreadState不包含Suspended,但System.Threading.ThreadState不包含System.Diagnostics.ThreadState。如何将System.Threading.ThreadState转换为{{1}},还是其他方法来检查它?我不是想暂停/恢复它们,只是我想知道Process黑客/进程资源管理器是如何做到的。

4 个答案:

答案 0 :(得分:7)

微软在.NET 1.0版中犯了一个大错误,他们添加了Thread.Suspend()和Resume()方法。这些方法被广泛滥用,程序员使用它们来实现线程同步。对他们来说完全不合适。问题是通常工作。但是在不幸的时候调用Suspend()并且当它被埋在Windows调用中时你将冻结一个线程,持有一个全局锁。并导致整个程序陷入僵局。

这不是他们唯一的设计错误,集合类上的Synchronized方法也是一个灾难。被广泛误解为“返回一个线程安全的集合”。

生活和学习,这一切都在.NET 2.0中得到修复。一个重大改进是Thread可能不再是操作系统线程,从未真正实现过。但解释了为什么有两个 ThreadState枚举,一个用于Thread(.NET版本),另一个用于ProcessThread(操作系统版本)。他们关闭了滥用Suspend / Resume的程序员的漏洞,这些方法被宣布为过时的。他们也关闭了后门,你无法从ProcessThread中找到一个线程被暂停。

功能,而不是错误。不要犯同样的错误,知道线程被暂停是无用的知识,它可能不会在一个微秒后暂停。

答案 1 :(得分:2)

操作系统线程与.Net线程不同。 Process.Threads返回OS线程,每个线程可能对应于.Net线程,也可能不对应.Net线程。

您可以查看ProcessThread.WaitReason,但它与.Net等待状态不对应

答案 2 :(得分:1)

这会对某人有所帮助。

        Process proc = Process.GetProcessById(31448);
        if(proc.Threads[0].WaitReason == ThreadWaitReason.Suspended)
        {
            //process is suspended
        }

答案 3 :(得分:0)

您可能会错误地使用SuspendThread或Wow64SuspendThread来查明它是否已被暂停,然后使用ResumeThread来恢复此情况。

SuspendThread返回:&#34;如果函数成功,则返回值是线程的先前暂停计数;&#34;

声明:

    [Flags] public enum ThreadAccess : int {
        TERMINATE = (0x0001),
        SUSPEND_RESUME = (0x0002),
        GET_CONTEXT = (0x0008),
        SET_CONTEXT = (0x0010),
        SET_INFORMATION = (0x0020),
        QUERY_INFORMATION = (0x0040),
        SET_THREAD_TOKEN = (0x0080),
        IMPERSONATE = (0x0100),
        DIRECT_IMPERSONATION = (0x0200)}

    [DllImport("kernel32.dll")]
        static extern IntPtr OpenThread(
        ThreadAccess dwDesiredAccess,
        bool bInheritHandle,
        uint dwThreadId);

    [DllImport("kernel32.dll")]
        static extern uint SuspendThread(IntPtr hThread);

    [DllImport("kernel32.dll")]
        static extern int ResumeThread(IntPtr hThread);

    [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)] 
        static extern bool CloseHandle(IntPtr handle);

(Wow64SuspendThread链接隐藏,因为我需要10个声誉来放置2个链接= ht.tps://msdn.microsoft.com/it-it/library/windows/desktop/ms687400(v = vs.85).aspx )