2013-08-16 36 views
4

我想检查进程的线程(整个进程)是否被挂起。 我这段代码获得每个进程的线程:进程线程(或整个进程)被挂起

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,或者是否有其他方法检查它?我不想暂停/恢复它们,只是想知道Process黑客/ Process Explorer如何执行此操作。

+1

System.Threading的一个很好,当然?你想做什么?在MSDN的诊断中,它说:“线程状态枚举只在少数调试场景中有用,你的代码不应该使用线程状态来同步线程的活动。”一般情况下,诊断不是你应该用于实际处理线程的东西 – Mattsjo

+2

操作系统线程与.Net线程不同。 'Process.Threads'返回操作系统线程,每个线程可能对应或不对应一个.Net线程。您可以查看['ProcessThread.WaitReason'](http://msdn.microsoft.com/zh-cn/library/system.diagnostics.processthread.waitreason.aspx),但它不对应于.Net等待状态。 –

+0

@Matthew沃森如果你会写这个答案我会批准它。 –

回答

7

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

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

生活和学习,这一切都得到了固定的.NET 2.0。一次大的改变是,一个线程可能不再是一个操作系统线程,从来没有真正实现过。但解释了为什么有两个 ThreadState枚举,一个用于Thread(.NET版本),另一个用于ProcessThread(操作系统版本)。他们关闭了程序员滥用Suspend/Resume的漏洞,这些方法被宣布已经过时。而且他们也关闭了后门,你无法从ProcessThread中发现线程被挂起。

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

+1

+1 - 我很喜欢听到关于.NET线程支持cockups的消息 - 这让我自己看起来不那么担心:) –

2

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

你可以看一下ProcessThread.WaitReason,但它不符合净等待状态

0

你可以使用不当SuspendThread或Wow64SuspendThread找出它是否被禁赛,然后用ResumeThread挽回局面。

SuspendThread return:“如果函数成功,则返回值是线程先前的暂停计数;”

声明:

[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)