2012-04-04 41 views
1

我有一個線程啓動實時監控功能,它基本上是打開串口並連續讀取串口數據。但是,如果我需要終止這個線程,我該怎麼做呢?因爲如果我沒有終止打開特定串口和讀數據的運行線程。當我關閉它並再次調用該函數時。相同的串行端口無法打開。我懷疑串口沒有正確關閉,仍然在單獨的線程中運行。所以我想我必須終止該線程,以便下次再次打開相同的串行端口。有沒有人有任何想法如何實現這一目標?winform中的線程化 - 緊湊的.NET Framework 3.5

我見過一些論壇說,Thread.Abort()是危險的使用。它只能用於最後的手段。

感謝您的幫助。

查爾斯

+0

您將需要以線程死態優雅的方式構造代碼。如果您發佈了一些代碼(線程正在執行的代碼),那麼提供有用的答案會更容易。 – 2012-04-04 22:30:14

回答

2

通常,您將設計在後臺線程中運行的方法來偵聽取消請求。這可以像布爾值一樣簡單:

//this simply provides a synchronized reference wrapper for the Boolean, 
//and prevents trying to "un-cancel" 
public class ThreadStatus 
{ 
    private bool cancelled; 

    private object syncObj = new Object(); 

    public void Cancel() {lock(syncObj){cancelled = true;}} 

    public bool IsCancelPending{get{lock(syncObj){return cancelled;}}} 
} 

public void RunListener(object status) 
{ 
    var threadStatus = (ThreadStatus)status; 

    var listener = new SerialPort("COM1"); 

    listener.Open(); 

    //this will loop until we cancel it, the port closes, 
    //or DoSomethingWithData indicates we should get out 
    while(!status.IsCancelPending 
     && listener.IsOpen 
     && DoSomethingWithData(listener.ReadExisting()) 
     Thread.Yield(); //avoid burning the CPU when there isn't anything for this thread 

    listener.Dispose(); 
} 

... 

Thread backgroundThread = new Thread(RunListener); 
ThreadStatus status = new ThreadStatus(); 
backgroundThread.Start(status); 

... 

//when you need to get out... 
//signal the thread to stop looping 
status.Cancel(); 
//and block this thread until the background thread ends normally. 
backgroundThread.Join() 
2

首先認爲你有線程它,你開始之前那麼他們將被自動關閉時退出應用程序關閉所有線程,你應該所有的人設置爲後臺線程。

然後再試試這樣:

Thread somethread = new Thread(...); 
someThread.IsBackground = true; 
someThread.Start(...); 

參考http://msdn.microsoft.com/en-us/library/aa457093.aspx

+0

+1 - 如果允許,我會添加更多。這是最簡單的方法。這只是一個串口讀取線程,所以誰在乎操作系統是否在關閉時破壞它!與用戶代碼不同,OS可以輕鬆應對循環和/或阻塞的線程。擺弄布爾「停止」標誌或定期檢查取消狀態最好不要完成。如果線程不是絕對需要被明確終止,那就不要這樣做! – 2012-04-04 23:01:12

+0

表單關閉後,該表單中的線程是否自動終止? – 2012-04-04 23:22:21

+0

@ Charles-Yes,當您退出應用程序時,它將終止所有線程。 – coder 2012-04-04 23:29:05

1

使用您最初設置爲false,當你想你的線程退出將其設置爲true的布爾標誌。顯然你的主線程循環需要監視那個標誌。當它看到它變成真,那麼你的輪詢,關閉端口並退出主線程循環。

主循環看起來是這樣的:

OpenPort(); 
while (!_Quit) 
{ 
    ... check if some data arrived 
    if (!_Quit) 
    { 
     ... process data 
    } 
} 
ClosePort(); 

取決於你如何等待新的數據你可能想以此來喚醒當你想你的線程充分利用事件(ManualResetEventAutoResetEvent)的它退出。