-3
下面的這個函數假裝擴展Thread.Sleep()
函數(或Win32 Sleep
/SleepEx
),它隻影響調用線程。給定一個線程的id或句柄,我如何確定線程的狀態?
在我的suspendFunc
lambda我想確保線程是否真的掛起,然後致電Thread.Sleep(TimeSpan)
。
我一直在尋找related Win32 thread functions從一個線程處理,線程ID檢索線程的狀態,但我並沒有發現類似的話,無論是我無法找到定義線程狀態的結構或枚舉(只managed one)所以我沒有找到任何提示開始做。
我該怎麼做到這一點?
(注:P /調用不共享代碼的形式提供,我認爲他們沒有必要了解,僅會增加代碼大小。)
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
我猜測線程的.NET實現跟蹤這些信息本身。更大的問題是爲什麼你要重新實現Thread.Sleep。對於初學者來說,這個功能的使用是一個設計不佳的程序的標誌。當然不是對另一個線程有意義的東西,這是你不擁有的東西。如果你想暫停這樣一個線程,調用'SuspendThread'函數。但是,真的,不要這樣做,因爲除非你正在編寫調試器,否則暫停一個線程是一個壞主意。否則,死鎖的城市。 –
暫停非擁有的線程並不意味着設計不良的程序,它在很多場景中都是非常有用,最好且唯一的方法,一個簡單的例子:如果您使用的是第三方命令行工具一個很長的任務(比如說FFMPEG,一個視頻轉換工具),並且你將它們的功能包裝在一個基於.NET的GUI中,然後你想在你的GUI中添加Pause/Resume功能,如果不需要SuspendThread/ResumeThread,你會與外部應用程序的線程互動來做這樣的事情嗎?你看,這很有道理。感謝評論! – ElektroStudios
聽起來不錯,但它是一個等待發生的史詩故障。如果這個長期任務是多線程的呢?你不能只掛起一個線程。是的,我想你可以暫停*全部* FFMPEG線程,但是你又回到了使用SuspendThread。不需要編寫所有這些代碼,也不需要這個問題。 –