C# 在C中的另一个线程内等待Comport值#

C# 在C中的另一个线程内等待Comport值#,c#,multithreading,C#,Multithreading,我创建了一个小程序。一切都很好,但现在我意识到我必须等待comport输入,所以我卡住了 这是我的DataReceived线程: void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e) { RxString = serialPort.ReadLine(); this.Invoke(new EventHandler(DisplayText)); } void Disp

我创建了一个小程序。一切都很好,但现在我意识到我必须等待comport输入,所以我卡住了


这是我的
DataReceived
线程:

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;
}
在这里,if和end以及其他东西都可以正常工作

但现在我有了另一个线程,在其中我必须等待comport输入接收,例如:“go”

我不发布整个代码,它有近200行

 private void AutostartClick(object sender, EventArgs e)
    {
 .... Do some Code
... Here i want to wait for "go"
... If go is received go ahead
}
我已经尝试了一段又一段时间,如果。。。但这不起作用,因为在这个过程中,我什么也没有收到

然后玩弄了
AutoResetEvent
,但它也失败了


我做错了什么?

我会做以下事情:由于
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
}
在应该等待“go”的方法中,只需等待事件发生:

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
}

我找到了一个解决办法。。。也许不是最好的方法,但它是有效的

使用ManualResetEvent或AutoResetEvent时,它始终冻结

我认为问题在于我处于一个while循环中,因此等待处理程序从未收到信号,因此它在这一点上冻结

现在我使用一个全局变量,DisplayText事件中的一个简单if和一个while,它调用this.Invoke(neweventhandler(DisplayText));而且它工作起来没有任何问题

以下是Serialport和DisplayText代码:

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
}

谢谢大家的帮助

“这是我的
DataReceived
thread”,它不是线程。当您没有需要串行端口输入的线程时,DataReceived事件非常有用。当你有这样一个线程时,它会变得非常有害,这需要你协调两个独立的线程。当您使用诸如RxString之类的全局变量时,您获得正确答案的几率几乎为零。只需删除事件处理程序并直接使用ReadLine()。谢谢您的回答。我想你的意思是,你已经接受了。。。我已经尝试实现这一点,但它与AutoResetEvent相同。。。整个应用程序freez:-(if(RxString.StartsWith(“go”))在我的代码中工作,但当我使用_goReceived.Set()和_goReceived.Onewait()运行它时,将不会通知停留在goReceived.Onewait()和goReceived.Wait()的代码。。。