我想检查进程的线程(整个进程)是否被挂起。 我通过以下代码获取每个进程线程:
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黑客/进程资源管理器是如何做到的。
答案 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 )