C#等待数据收到并转到下一次迭代

时间:2016-12-26 17:02:27

标签: c# serial-port

我正在使用串行端口从设备中获取for循环迭代的数据。 问题在于循环迭代我需要从串口获取数据,验证它并进入下一次迭代。 我怎么能做到这一点?

以下是我的代码:

private void processData()
{
    // Loop Procedure 
    int x = Int32.Parse(master["Cycle"].ToString());
    int y = Int32.Parse(master["MinWeight"].ToString());

    // Loop for each line
    for (int i = this.CLine; i < 2; i++)
    {
        this.CLine = i;
        if (i == 0)
            label15.Text = master["LLINE"].ToString();
        else
            label15.Text = master["RLINE"].ToString();

        IDictionary<string, string> dic = (Dictionary<String, String>)master[i.ToString()];
        label18.Text = this.CProcess = dic["PROCESSID"];
        int z = Int32.Parse(dic["PRODLANE"].ToString());

        // Loop for each sampling session (Cycle)
        for (int j = this.CCycle; j <= x; j++)
        {
            this.CCycle = j; 

            // Loop for production lane
            for (int k = this.CLane; k <= z; k++)
            {
                this.CLane = k;
                label16.Text = k.ToString(); 


                // In this section i want to send command over serial port
                // get value from my device
                // validate it if current weight bellow standard weight
                // do it again (get data from device)
                // else we can go to next iteration

                while (this.CWeight < y)
                {
                    XApi.l("xxx2 " + this.CWeight + " vs " + y + " " + k.ToString() + " " + this.isDataReady); 
                    SendData("Q"); 
                }

                // Commit Transaction
                // XDb.CommitTrans(this.CCycle.ToString(), dic["LINEID"].ToString(), this.CLane.ToString(), weight.ToString(), this.isTrialStage == true ? "1" : "0");   
            }
        }
    }
}

我试过这个

while (this.CWeight < y)
{
    XApi.l("xxx2 " + this.CWeight + " vs " + y + " " + k.ToString() + " " + this.isDataReady); 
    SendData("Q"); 
}

但它似乎阻止了UI线程并使我的应用程序太过分了。 谁能给我一些想法?提前谢谢。

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    if (e.EventType == System.IO.Ports.SerialData.Eof) 
        return;

    // If the com port has been closed, do nothing
    if (!comport.IsOpen) 
        return;

    // Update flag data received
    this.isDataReady = true;

    // Determain which mode (string or binary) the user is in
    if (CurrentDataMode == DataMode.Text)
    {
        // Read all the data waiting in the buffer
        string data = comport.ReadExisting();

        // Update result        
        result += data;

        if (result.Length > 16)
        { 
            SetText(result.ToString());
        }

        // Display the text to the user in the terminal
        Log(LogMsgType.Incoming, data);
    }
    else
    {
        // Obtain the number of bytes waiting in the port's buffer
        int bytes = comport.BytesToRead;

        // Create a byte array buffer to hold the incoming data
        byte[] buffer = new byte[bytes];

        // Read the data from the port and store it in our buffer
        comport.Read(buffer, 0, bytes);

        // Show the user the incoming data in hex format
        Log(LogMsgType.Incoming, ByteArrayToHexString(buffer));
    }
}

private void SendData(String msg)
    {
        this.isDataReady = false;
        result = "";
        if (CurrentDataMode == DataMode.Text)
        {
            // Send the user's text straight out the port
            comport.Write(msg + "\r\n");

            // Show in the terminal window the user's text
            Log(LogMsgType.Outgoing, msg + "\n");
        }
        else
        {
            try
            {
                // Convert the user's string of hex digits (ex: B4 CA E2) to a byte array
                byte[] data = HexStringToByteArray(txtSendData.Text);

                // Send the binary data out the port
                comport.Write(data, 0, data.Length);

                // Show the hex digits on in the terminal window 
                Log(LogMsgType.Outgoing, ByteArrayToHexString(data) + "\n"); 
            }
            catch (FormatException)
            {
                // Inform the user if the hex string was not properly formatted
                Log(LogMsgType.Error, "Not properly formatted hex string: " + txtSendData.Text + "\n");
            }
        } 
    }

1 个答案:

答案 0 :(得分:4)

  

任何人都可以给我一些想法吗?

您可以在代码中使用async / await,不要通过编写如下所示的扩展方法来阻止您的UI。用法是:

async void SomeMethod()
{
    SerialPort serialPort = .......

    while (true)
    {
        serialPort.Write(.....);
        var retval = await serialPort.ReadAsync();
    }  

}

此处的关键字是使用TaskCompletionSource类与您的活动...

static public class SerialPortExtensions
{
    public static Task<byte[]> ReadAsync(this SerialPort serialPort)
    {
        var tcs = new TaskCompletionSource<byte[]>();
        SerialDataReceivedEventHandler dataReceived = null;
        dataReceived = (s, e) =>
        {
            serialPort.DataReceived -= dataReceived;
            var buf = new byte[serialPort.BytesToRead];
            serialPort.Read(buf, 0, buf.Length);
            tcs.TrySetResult(buf);
        };
        serialPort.DataReceived += dataReceived;
        return tcs.Task;
    }
}