2009-03-05 67 views
9

我最近試圖使用backgroundworker而不是「經典」線程,並且我意識到它至少對我來說造成了比解決方案更多的問題。 我有一個backgroundworker運行一個同步讀取(在這種情況下,從串口),並在1代碼行約30秒阻塞,然後取消懸而未決的解決方案。我看到,如果應用程序在此時關閉(無論是使用十字按鈕還是Application.Exit()),該進程都會永久保持殭屍狀態。Backgroundworker abort

我需要一種方法來強制中止或殺死backgroundworker線程。

回答

2

我不是很確定你要完成什麼,但也許SerialPort.DataReceived事件是一個更好的解決方案?

如果你已經精通線程的使用,我沒有看到使用BackgroundWorker的重點。它專爲那些首先不瞭解線程的人設計。

此外,我不喜歡中止線程的想法。感覺很危險,多線程應用程序不需要再冒險。

+0

我發現SerialPort.DataReceived是在CF有點混亂,不知道該IMPL是FF更好。 CF使用的線程數量比您期望的要多,所以要小心。 – Quibblesome 2009-03-05 11:13:13

+10

對於有關BackgroundWorker的註釋,幾乎試圖-1;它旨在強制執行一些標準並自動將事件封送到UI線程,這是使用它的有效原因;不理解線程會導致問題,無論你走哪條路。 – 2010-10-12 10:31:51

+0

除非有一種更簡單的方法來與正常線程的UI線程同步... – Glimpse 2014-06-12 21:21:29

2

我不認爲BackgroundWorker支持殺死線程。取消操作必須在執行作業的方法中完成。在你的情況下,我認爲一個普通的線程將是最好的選擇。

3

該進程不應該成爲殭屍,因爲BackgroundWorker線程被標記爲「背景」,並應在用戶界面關閉時結束。

5

我把一個在一起,(我認爲)做這項工作。請讓我知道如果我沒有關閉。 這是一個它如何工作的簡單例子。

var backgroundWorker = new BackgroundWorker(){WorkerSupportsCancellation = true}; 

backgroundWorker.DoWork += (sender, args) => 
     {     
       var thisWorker = sender as BackgroundWorker; 
       var _child = new Thread(() => 
               { 
                //..Do Some Code 

               }); 
       _child .Start(); 
       while (_child.IsAlive) 
       { 
        if (thisWorker.CancellationPending) 
        { 
         _child.Abort(); 
         args.Cancel = true; 
        } 
        Thread.SpinWait(1); 
       }     
     }; 

backgroundWorker.RunWorkerAsync(parameter); 
//..Do Something... 
backgroundWorker.CancelAsync(); 

由於後臺工作人員是線程池的一部分,我們不想中止它。但是我們可以在內部運行一個線程,我們可以允許中止發生。然後,backgroundWorker會基本上運行,直到子線程完成或者我們發信號通知它終止進程。後臺工作線程然後可以返回到讀取池中。通常,我會將其包裝在一個助手類中,並通過委託方法傳遞後臺線程作爲參數傳入並在子線程中運行。

請有人讓我知道如果我撞我的頭靠在牆上,但它似乎工作正常..但多數民衆贊成在線程的問題是不是它..你可以得到不同的結果,當你在不同的時間運行它。

0

你可以試試這個:

  backgroundworker.Dispose(); 
      backgroundworker = null; 
      GC.Collect(); //this helps cleans up ram