簡體   English   中英

在多線程C#應用程序中正確終止線程

[英]Proper thread termination in multi-threaded C# application

我認為這是一個相當復雜的問題。 我有一個C#應用程序,它使用反射的插件架構。 應用程序加載插件dll,用戶可以啟用/禁用它們。 啟用插件后,主應用程序會啟動一個線程來運行插件。在許多情況下,插件可能有多個自己的線程。 當我想禁用一個插件時,我正在調用Thread.Abort()。 這似乎會破壞為插件創建的初始線程,但插件創建的任何其他線程都會繼續運行。 有沒有更好的方法來阻止所有相關的插件線程和主線程?

謝謝。

不要將Thread.Abort用於此目的。

添加Shutdown方法或類似於您的插件API,並要求您的插件干凈地關閉。 如果您需要保護自己免受拒絕關閉的惡意插件的影響,請在他們自己的AppDomain中運行它們並在必要時終止AppDomain。

我會在插件中設置一個我希望關閉它的標志,插件本身應該定期檢查標志是否已設置,如果是,它應該自行清理。 這種方法最適合使用一段while(true) {...}種線程體。

如果您使用基於事件的aproach與大量的WaitForSingleObject ,我會使用一個事件,當我想要插件關閉時,我將脈沖,我將事件添加到WaitForMultipleObjects列表進行檢查。

這實際上取決於您的插件如何運行以及它的編碼方式。 嘗試提供更多信息。

Thread.Abort是一種可怕的方式,它根本不進行任何清理。

是的,不要使用Abort。 當我想終止執行時,我會使用ManualResetEvent來發出信號,例如使用循環:

ManualResetEvent _stopping = new ManualResetEvent(false);
...
while (!_stopping.WaitOne(0))
{
    ...
}

當你想要停止循環時發出信號:

public void Stop()
{
    _stopping.Set();
}

然后使用Thread.Join,如果你想等到線程終止。 如果沒有及時,你可以打電話給Abort。

在您的情況下,您應該真正將加載項加載到單獨的AppDomain中,並在完成后卸載它。 您可能希望構建一個模型,在該模型中,當它們即將關閉時,您也會發送加載項通知。

首先,你真的應該避免使用Thread.Abort作為終止線程的手段。 我不知道你是否可以控制插件的實現,但如果你這樣做,你應該重新考慮這個設計。 閱讀有關相關問題的更多細節Thread.Abort

至於如何讓其他線程停止插件創建,再次 - 你想在你的代碼和插件之間設計一個接口,優雅地通知插件你希望它停止它正在做的事情。

我知道沒有辦法詢問線程有關誰可能聲稱自己是擁有者的線索。 這基本上意味着你需要在你的插件API中添加approriate機制來關閉插件實例。 也許您可以在插件界面中添加ShutdownTerminate方法,並使其成為記錄合同的一部分,這些合同必須能夠很好地清理他們分配的所有資源。

我能想到的唯一另一個策略(這個很糟糕的時候)是跟蹤應用程序自己創建的所有線程,然后假設所有其他線程都由插件擁有。 您將不得不中止所有這些線程,因為您無法將它們鏈接到插件的特定實例。 就個人而言,這聽起來像是災難的秘訣。 我只會探索這個作為最后的手段。

聽起來像你在各種程序集上調用任意方法,這些方法可能不是設計為在線程上運行而期望它們可能被取消。
在它自己的線程上運行的插件方法至少應該處理異常並清理它自己的線程。 在線程上調用Thread.Abort()時,會在該線程上拋出ThreadAbortException以終止它。

Thread.Abort()不是在正常條件下終止線程的推薦方法。 更好的方法是在方法中設計一種合作方式,允許您取消它。 如果這是不可能的,只要執行方法偶爾在安全點進入WaitSleepJoin狀態(等待WaitHandle,休眠等),調用Thread.Interrupt()是一種更溫和的終止線程的方法。 在這種情況下,線程上拋出ThreadInterruptedException。 其他線程仍應在異常處理程序中清理。

其他人都是對的 - 在優雅的關機信號中編碼。 但是,如果您無法輕易更改子線程的代碼,並且您的計划壓力很大,並且如果子線程重置或掛起中止的可能性很小,並且您承諾稍后重構,那么您可以為插件添加一個故障保護,將子線程添加到集合中,然后捕獲ThreadAbortException並使集合中止子線程。

暫無
暫無

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

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