2016-05-04 9 views
1

私は小さなプログラムを作成しました。何もうまくいきますが、今は私がコンパイル入力を待たなければならないことを認識しました。ここで私は固執しました。終了および他のものとの場合は正常に動作します。ここCの他のスレッドの中でComport値を待つ

void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
    RxString = serialPort.ReadLine(); 
    this.Invoke(new EventHandler(DisplayText)); 
    } 
    void DisplayText(object sender, EventArgs e) 
{ 
String RxString1 = RxString+("\n"); 

if (RxString1 == "END\n") { 
    stopauto = "stop"; 
    autostart.Enabled = true; 
    autostop.Enabled = false; 
} 

は、ここに私のDataReceivedスレッドです。

しかし、今私は別のスレッドを持っています。その中には、私がcomport入力を受け取るのを待たなければなりません。例えば、 "go"です。

私はしばらくの間とし、もしながらA、それを試してみました

private void AutostartClick(object sender, EventArgs e) 
    { 
.... Do some Code 
... Here i want to wait for "go" 
... If go is received go ahead 
} 

私はそれが200本のラインの近くにあり、全体のコードを投稿していない... ...しかし、これは内部のために動作しません。私はそのコンポートから何も受け取っていません。

AutoResetEventで再生しましたが、あまりにも詰まっています。

私は間違っていますか?

+1

"これは私の' DataReceived'スレッド "です。これはスレッドではありません。 – Aron

+1

DataReceivedイベントは、シリアルポート入力が必要なスレッドを*持っていない場合に便利です。あなたが2つの別々のスレッドを調整するようなスレッドを持っていると、それは積極的に有害になります。 * RxString *のようなグローバル変数を使用すると、その権利を得る確率はゼロに近くなります。単にイベントハンドラを削除し、ReadLine()を直接使用してください。 –

答えて

0

私は解決策...そうでないかもしれない最善の方法を発見したが、それは動作します。

ManualResetEventまたはAutoResetEventでは、常にフリーズします。

問題は私がwhileループであったため、待機ハンドラがこの時点でフリーズすることはありませんでした。

私はDisplayTextイベントの場合はシンプルで、this.Invoke(new EventHandler(DisplayText))を呼び出す場合はグローバル変数を使用します。何の問題もなく動作します。ここで

はSERIALPORTと表示テキストコード:

String waitvar = ""; // Global wait Variable 

void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
RxString = serialPort.ReadLine(); 
this.Invoke(new EventHandler(DisplayText)); 
} 

void DisplayText(object sender, EventArgs e) 
{ 
String RxString1 = RxString+("\n"); 

if (RxString1 == "go\n") { 
    waitvar = "go"; 
} 
comview.AppendText(RxString1); 
} 

て待つ点で:

private void AutostartClick(object sender, EventArgs e) 
{ 
.... Do some Code 

// Wait here 

while (waitvar != "go") 
{ 
this.Invoke(new EventHandler(DisplayText)); 
} 

.... Do some Code 
} 

は、すべてのヘルパーに感謝します!

1

私は次のことを行います:SerialPortコンポーネントのDataReceivedイベントが別のスレッドで実行されるため、メインスレッドが待っていても実行されることは確実です。

これは、必要な「キーワード」を受信した場合、あなたがWaitHandleを設定することができます、そしてあなたが発生し、このイベントを待つことができます。

「行く」のを待つ必要があり、あなたの方法では
private ManualResetEvent _goReceived = new ManualResetEvent(false); // Initialize as "not set" 

void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    RxString = serialPort.ReadLine(); 

    // DO NOT CALL DISPLAYTEXT IF YOU RECEIVE "GO" - THE MAIN THREAD IS BLOCKED! 
    if (RxString.StartsWith("go")) 
    { 
     _goReceived.Set(); 
    } 
    else 
    { 
     this.Invoke(new EventHandler(DisplayText)); 
    } 
} 

void DisplayText(object sender, EventArgs e) 
{ 
    String RxString1 = RxString+("\n"); 

    if (RxString1 == "END\n") { 
     stopauto = "stop"; 
     autostart.Enabled = true; 
     autostop.Enabled = false; 
    } 
} 

、待つだけイベントが発生するために:

private void AutostartClick(object sender, EventArgs e) 
{ 
    .... Do some Code 

    // Wait for "go" and THEN call DisplayText instead of calling 
    // it above 
    _goReceived.Wait(); 
    DisplayText(); 

    // Reset the event to make this works more than just once 
    _goReceived.Reset(); 

    ... If go is received go ahead 
} 
+0

回答ありがとうございます。 私はあなたが意味すると思う_goReceived.OneWait(); ... 私はこれを実装しようとしましたが、AutoResetEventと同じです...アプリケーション全体freez :-( if if(RxString.StartsWith( "go"))は自分のコードで動作しますが、 _goReceived.Set();および_goReceived.Onewait();を実行し、コードがgoReceived.Onewait();およびgoReceived.Wait();で停止したことが通知されません。 – Phantom001

関連する問題