如何处理DataReceived

时间:2018-04-07 02:35:35

标签: c# wpf event-handling

请参阅下面的代码,我正在尝试返回到我注册端口的DataReceived事件的方法。基本上,如果我在读取超时之前从端口接收数据。我将返回我注册DataReceived事件和degister并继续处理的位置。我试图用while循环来做。但不确定它是否准确,这是必须要做的事情 或者如果有其他方法可以做到这一点。

public class CommClass{
private static byte[] portReturn = null;

private void setUpDevice()
{
    byte[] command = { 0x11,0X51 };
    try
    {
        port.DataReceived += new SerialDataReceivedEventHandler(serialPortDataReceived);
        port.Write(command, 0, command.Length);
        while (portReturn == null) { } //Not sure if this will work. If I receive data before times out I do not want to wait in the loop.
        port.DataReceived -= serialPortDataReceived;
    }
    catch(Exception ex)
    {
        //to do
    }
}


private void serialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
    var servicePort = (SerialPort)sender;
    portReturn = servicePort.ReadByte();
    return;
}
}

1 个答案:

答案 0 :(得分:2)

你的代码在技术上会起作用;但是,当您等待数据进入时,您的while循环将最大化您的CPU,这不是您想要的。我建议在这里使用ManualResetEvent让您等待以CPU友好的方式接收数据。您可以阅读有关他们的更多信息here

public class CommClass
{
    private static byte[] portReturn = null;

    // ManualResetEvents are great for signaling events across threads
    private static ManualResetEvent dataReceivedEvent = new ManualResetEvent(false);

    private void setUpDevice()
    {
        byte[] command = { 0x11,0X51 };
        try
        {
            port.DataReceived += new SerialDataReceivedEventHandler(serialPortDataReceived);
            port.Write(command, 0, command.Length);

            // Wait for the event to be set without spinning in a loop.
            // Can also specify a timeout period to wait in case the data never comes.
            dataReceivedEvent.WaitOne();

            // Reset the event so that you can use it again later if necessary
            dataReceivedEvent.Reset();

            port.DataReceived -= serialPortDataReceived;
        }
        catch(Exception ex)
        {
            //to do
        }
    }


    private void serialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        var servicePort = (SerialPort)sender;
        portReturn = servicePort.ReadByte();

        // Set the event to let the main thread know you have received data
        dataReceivedEvent.Set();
    }
}