2016-12-13 16 views
0

シリアル通信を制御するスレッドを生成するプログラムがあります。シリアルポートでの応答を待つ間、私はAutoResetEventでスレッドをブロックします。ブロックされたスレッドがイベントを発動できますか?

ブロックされているためにデータを受信したときに、そのスレッドはイベントを実行できませんか?

この点を説明するために、以下に私のコードの簡単なバージョンがあります。このコードによってデッドロックが発生するか、ブロックされたスレッドでイベントが実行される可能性がありますか?

AutoResetEvent rxDataReady = new AutoResetEvent(false); 

public void GetSomeDataFromSerialPort() 
{ 
    SerialPort sp = new SerialPort() 
    sp.Write(dataRequest) 

    rxDataReady.WaitOne(); 

    // Process data 
} 

private void ReadDataEventHandler(object sender, SerialDataReceivedEventArgs e) 
{ 
    // Prepare data 
    rxDataReady.Set(); 
} 

答えて

4

発言MSDN SerialPort.DataReceived

DataReceivedイベントは、データがSERIALPORTオブジェクトから受信されるスレッドで発生しますから、どうもありがとうございまし

私はあなたのコードサンプルがデッドロックに終わるとは思わない。

しかし、タイトルにあなたの質問への答え:

は、ブロックされたスレッドの火災事象できますか?

1

タイトルで質問に答えるために:いいえAは、スレッドがイベントを発生させることができないブロックされました。 ただし、イベントを発生させる原因となるスレッドが異なる場合は、期待どおりに動作するはずです。これを説明するために

は、ここでの例です:

internal class Program 
{ 
    private static readonly AutoResetEvent RxDataReady = new AutoResetEvent(false); 

    private static event EventHandler ev; 

    public static void GetSomeDataFromSerialPort() 
    { 
     RxDataReady.WaitOne(); 

     // Process data 
    } 

    private static void Main() 
    { 
     ev += ReadDataEventHandler; 
     Task.Run(
      async() => 
       { 
        await Task.Delay(5000); 
        ev(null, EventArgs.Empty); 
       }); 
     GetSomeDataFromSerialPort(); 

     Console.WriteLine("Done."); 
     Console.ReadLine(); 
    } 

    private static void ReadDataEventHandler(object sender, EventArgs eventArgs) 
    { 
     // Prepare data 
     RxDataReady.Set(); 
    } 
} 

何このコードがないことは、単純に5秒間待機してからイベントを発生させる新しいスレッドを開始しています。 これを実行しようとすると、5秒後に「完了」と表示されます。コンソールに表示されます。あなたが同じスレッドでイベントを発生させるとしたら

は:

private static void Main() 
    { 
     ev += ReadDataEventHandler; 
     GetSomeDataFromSerialPort(); 
     ev(null, EventArgs.Empty); 

     Console.WriteLine("Done."); 
     Console.ReadLine(); 
    } 

を次にイベントが発生することはないだろう、と実行はRxDataReady.WaitOne()を超えて継続することはありません。

これに代わる方法は、GetSomeDataFromSerialPort()を別のスレッドで実行することです。

+1

@Diryboyの回答は、SerialPort.Dataに関してよりよくなります。具体的には、私がより一般的な答えを示しています。 – eitamal

関連する問題