簡體   English   中英

停止線程的最佳方法

[英]Best way to stop a thread

我正在線程池中使用線程來執行某些操作。 現在,在某些情況下,如果出現問題,我想關閉表格。 我有一個try / catch-block,如果它捕獲了某些內容,則應該執行某些操作,然后關閉表單。 問題是,當關閉時,線程在后台繼續運行,然后在我調用某些內容的地方引發異常,因為該句柄不再存在。

好吧,所以我需要停止線程,以便它不會繼續。 我聽說'Abort'不是一個好的解決方案,我應該做一個flag變量並進行查詢,但是我應該怎么做呢? 有沒有更好的辦法? 如果您需要代碼,請告訴我,但這是一個更普遍的問題。

謝謝!

我不確定是什么問題,因為您沒有提供代碼,但是也許您應該檢查InvokeRequired屬性,請嘗試以下操作:

if (Control.InvokeRequired)
{
// your code
}

我通常有一個標志,當窗體關閉時,或者由於其他任何原因我需要線程終止時,該標志都設置為true。

另一個有用的操作是將IsBackground屬性設置為true ,這使進程在最后一個窗體關閉時終止,而不是讓幻像進程運行。

例如,如果您有一個生成線程的表單,該線程會在一段while (true)定期進行計算, while (true)必須在表單關閉時以某種方式手動終止該線程。 如果將IsBackground = true設置,則線程將不會阻止進程終止。

(但是,當然,您還應該記住,如果線程以某種方式與表單交互,則需要處理該線程,否則,當表單不再能夠訪問已處置的對象時,關閉表單可能會在線程中引起異常。等)

您必須確保線程正確執行到最后並且干凈。 之后,您可以關閉表單並刪除線程對象。

這就是我通常處理所有線程的方式。 我使用一堆“信號”變量(在自己的類中定義)來允許我控制線程並從應用程序線程檢查其狀態。 如果您嘗試抓住某些東西,那就太好了! 只是通過完全掉線直到其運行空閑來“中止”該功能。 線程完全完成后,您可以安全地將其刪除。

    void MyThreadFunction () {
      bThreadActive = true;

      while(!bThreadTerminate){
        bThreadIdle = false;  //thread is no longer idle.
        bThreadStart = false; //Reset this too 

        //Do all your thread stuff here.
          doSomething();

        while(!bThreadTerminate){
          //Stay here until we start or terminate
          bThreadIdle = true;

          if(bThreadStart)
            break;
        }
      }

      bThreadActive = false;
    }

    void doSomething(){
      //Anytime you go into a loop and if statements, check if it's been terminated.
      //When you set bThreadTerminate to true, exit the thread without any further calculations.
      //Any logical statement needs to also check if you want to terminate the thread.

      int iNum1 = 1;
      int iNum2 = 1;

      try {
        if(iNum1 == iNum2 && !bThreadTerminate){
        //Stuff to do.
        }
      }catch(Exception *e){
        //Abort Code here
      }
    }

因此,基本上,這將執行一次所有操作,然后等到您需要再次執行此操作(在您的通話中)。 將bStart設置為true,它將一直循環直到它再次空閑為止。 如果將bThreadTerminate設置為true,則在主線程上,您將等到bActive為false才刪除它。

我希望這有幫助。

好吧,我設法做到了,任務實際上非常簡單。

您必須聲明一個CancellationTokenSource和一個Action才能執行void / function。 像那樣:

CancellationTokenSource cancellationToken = new CancellationTokenSource();
Action yourAction;

然后使用void初始化動作以執行:

yourAction = anyvoid;

最后:

yourAction.BeginInvoke(yourAction.EndInvoke, null); 

那就是你開始的方式。 現在,當您需要取消/停止線程時,請繼續說:

cancellationToken.Cancel();

之后,它將取消線程。 為避免線程在這段時間內繼續運行,只需在所有“取消”執行之后進行查詢。

if (cancellationToken.IsCancellationRequested)
  return;

而已。 優點是,您不必處理任何AbortExceptions或任何東西,這是imo停止線程的一種干凈方法。

暫無
暫無

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

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