给定一个主题的id或句柄,我如何确定该主题的状态?

时间:2016-05-29 11:32:17

标签: c# .net vb.net winapi asynchronous

下面这个函数假装扩展只影响调用线程的Thread.Sleep()函数(或Win32 Sleep / SleepEx)。

在我的suspendFunc lambda中,我想在调用Thread.Sleep(TimeSpan)之前确保线程是否真的被暂停。

我一直在搜索 related Win32 thread functions 从线程句柄或线程ID中检索线程的状态,但我没有找到类似的东西,我无法找到定义线程状态的结构或枚举(只有 managed one )所以我没有找到任何提示开始这样做。

我怎么能这样做?。

(注意:共享代码中没有提供P / Invokes,我认为它们没有必要理解,只会增加代码大小。)

C#:

public static void SleepThread(int threadId, TimeSpan timespan)
{
    IntPtr hThread = default(IntPtr);
    int win32Err = 0;

    // Returns the previous suspend count for the thread.
    Func<int> suspendFunc = () =>
    {
        int suspendCount = 0;
        Debug.WriteLine("Sleeping...");
        Thread.Sleep(timespan);
        Debug.WriteLine("Resuming thread...");
        suspendCount = ResumeThread(hThread);
        CloseHandle(hThread);
        return suspendCount;
    };

    hThread = OpenThread(ThreadAccessRights.SuspendResume | ThreadAccessRights.Terminate, true, threadId);
    win32Err = Marshal.GetLastWin32Error();

    if ((hThread == IntPtr.Zero)) {
        throw new Win32Exception(win32Err);

    } else {
        Debug.WriteLine("Pausing thread...");
        Task<int> suspendTask = Task.Factory.StartNew<int>(suspendFunc);
        SuspendThread64(hThread);

    }

}

//=======================================================
//Service provided by Telerik (www.telerik.com)
//=======================================================

VB.NET:

Public Shared Sub SleepThread(ByVal threadId As Integer, ByVal timespan As TimeSpan)

    Dim hThread As IntPtr
    Dim win32Err As Integer

    Dim suspendFunc As Func(Of Integer) =
        Function() As Integer ' Returns the previous suspend count for the thread.
            Dim suspendCount As Integer
            Debug.WriteLine("Sleeping...")
            Thread.Sleep(timespan)
            Debug.WriteLine("Resuming thread...")
            suspendCount = ResumeThread(hThread)
            CloseHandle(hThread)
            Return suspendCount
        End Function

    hThread = OpenThread(ThreadAccessRights.SuspendResume Or ThreadAccessRights.Terminate, True, threadId)
    win32Err = Marshal.GetLastWin32Error()

    If (hThread = IntPtr.Zero) Then
        Throw New Win32Exception(win32Err)

    Else
        Debug.WriteLine("Pausing thread...")
        Dim suspendTask As Task(Of Integer) = Task.Factory.StartNew(Of Integer)(suspendFunc)
        SuspendThread64(hThread)

    End If

End Sub

1 个答案:

答案 0 :(得分:3)

这是我能得到的最接近的。

Function GetThreadState(ProcId As Integer, ThreadId As Integer) As Threading.ThreadState
    For Each Thr As Threading.Thread In Process.GetProcessById(ProcId).Threads
        If Thr.ManagedThreadId = ThreadId Then Return Thr.ThreadState
    Next
    Throw New ArgumentOutOfRangeException("Thread not found.")
End Function