簡體   English   中英

C#掛起所有線程

[英]C# suspending all threads

我有一個可能相當獨特的問題。 我有一個應用程序,當我不在場時長時間在無頭盒子上運行,但並不重要。 我希望能夠使用Visual Studio遠程調試此應用程序。 為了做到這一點,我有這樣的代碼:

// Suspend all other threads to prevent loss
// of state while we investigate the issue.
SuspendAllButCurrentThread();
var remoteDebuggerProcess = new Process
    {
        StartInfo =
            {
                UseShellExecute = true,
                FileName = MsVsMonPath;
            }
    };
// Exception handling and early return removed here for brevity.
remoteDebuggerProcess.Start();

// Wait for a debugger attach.
while (!Debugger.IsAttached)
{
    Thread.Sleep(500);
}
Debugger.Break();

// Once we get here, we've hit continue in the debugger. Restore all of our threads,
// then get rid of the remote debugging tools.
ResumeAllButCurrentThread();

remoteDebuggerProcess.CloseMainWindow();
remoteDebuggerProcess.WaitForExit();

這個想法是這樣的,我在我離開的時候遇到了一個錯誤,並且應用程序有效地暫停了自己並等待遠程調試器連接,在第一次繼續之后,由於Debugger.Break調用,它會自動獲得正確的上下文。

問題在於:實現SuspendAllButCurrentThread是非常重要的。 不推薦使用Thread.Suspend ,我不能P / Invoke到SuspendThread因為托管線程和本機線程之間沒有一對一的映射(因為我需要保持當前線程處於活動狀態)。 如果可以避免,我不想在有問題的機器上安裝Visual Studio。 我怎樣才能做到這一點?

我不能P / Invoke到SuspendThread,因為托管線程和本機線程之間沒有一對一的映射

您也不能枚舉托管線程,只能枚舉非托管線程。 實際上它們之間一個一對一的映射,他們只是使它很難找到它。 最初的目的是允許創建一個不使用操作系統線程來實現Thread的自定義CLR主機,這是SQL Server組要求使用光纖的請求。 從來沒有成功,他們無法讓它足夠可靠。 不存在不使用實際操作系統線程的實際CLR主機。

所以你實際上可以使用Process.GetCurrentProcess()。線程來枚舉你所有的線程。 並避免通過pinvoking GetCurrentThreadId()暫停您自己的,將它與ProcessThread.Id進行比較

這樣做的可靠性是一種猜測,不要試圖做任何激烈的事情,如發送警報提醒您是時候連接調試器了。 您可能已經暫停了在Windows中執行代碼並獲得全局鎖定的線程。 以及CLR工作線程,如終結器線程或后台GC線程。

更好的方法是使用一個單獨的保護進程來完成所有這些,就像調試器一樣。 使用您在后台程序中創建的命名EventWaitHandle和主程序中的OpenExisting()。 保護程序需要等待句柄以及進程的WaitAny()。 你的主程序現在可以簡單地調用Set()來喚醒守衛程序。 現在可以安全地暫停所有線程。

Thread.Suspend的主要問題是它可能會使某些對象處於不可用狀態。

文檔

不要使用Suspend和Resume方法來同步線程的活動。 暫停它時,您無法知道線程正在執行的代碼。 如果在安全權限評估期間掛起線程時掛起線程,則可能會阻止AppDomain中的其他線程。 如果在執行類構造函數時掛起線程,則會阻止AppDomain中嘗試使用該類的其他線程。 死鎖很容易發生。

因此,當您嘗試查看此類尚未使用的對象的內容時,您可能也會被鎖定。 因此,無論您使用什么來暫停其他線程,您都可能在同一場景中結束。 所以,唯一的可能性就是修改其他線程的實現,以便能夠讓它們自行掛起: 有沒有辦法無限期地暫停一個線程?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM