2012-04-04 7 views
1

私はライブ監視を開始する関数にスレッドを持っています。これは基本的にシリアルポートを開き、シリアルポートからデータを連続的に読み込みます。ただし、このスレッドを終了する必要がある場合、どうすればよいですか?なぜなら、特定のシリアルポートを開いてデータを読み込んでいる実行中のスレッドを終了しなければならないからです。私はそれを閉じて、再び関数を呼び出します。同じシリアルポートを開くことはできません。シリアルポートが正しく閉じられておらず、まだ別のスレッドで実行されていると思われます。ですから、次回同じシリアルポートを開くには、そのスレッドを終了する必要があると思います。誰にどのようにこれを達成するための任意のアイデアがありますか?winformのスレッド - コンパクト.NET Framework 3.5

Thread.Abort()が使用するのは危険であるとのフォーラムがあります。最後の手段としてのみ使用してください。

ありがとうございました。

チャールズ

+0

スレッドが正常に終了するようにコードを構造化する必要があります。いくつかのコード(スレッドが実行しているコード)を投稿すると、有益な答えを提供するのが簡単になります。 –

答えて

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(...); 

は、あなたが最初にfalseに設定すると、あなたのスレッドが終了したいときにtrueに設定するブールフラグを使用しhttp://msdn.microsoft.com/en-us/library/aa457093.aspx

+0

+1 - 許可されていればさらに追加します。それは最も簡単な方法です。それは単なるシリアルポート読み取りスレッドなので、OSがシャットダウン時にOSを破壊するかどうかは誰ですか? OSは、ユーザコードとは異なり、ループやブロックされたスレッドに簡単に対処できます。ブーリアン「ストップ」フラグをつけたり、定期的にキャンセル状態をチェックしたりするのは、まったくやっていないのがベストです。スレッドが無条件に明示的に終了する必要がない場合は、実行しないでください。 –

+0

フォームが閉じられると、そのフォームのスレッドは自動的に終了しますか? –

+0

@ Charles-はい、アプリケーション終了時にすべてのスレッドを一度終了します。 – coder

1

を参照してください。どうやら、あなたのメインスレッドループは、そのフラグを監視する必要があります。それが本当にポーリングに変わったのを見たら、ポートを閉じてメインのスレッドループを終了します。

あなたのメインループは次のようになります。

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

新しいデータを待つ方法に応じてあなたが欲しいあなたのスレッドをウェイクアップするために、イベント(ManualResetEventまたはAutoResetEvent)を利用することもできますそれをやめる。

関連する問題