C# 等待直到收到数据并进入下一次迭代 [英] C# Wait until data received and go to next iteration

查看:64
本文介绍了C# 等待直到收到数据并进入下一次迭代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用串行端口从设备获取数据以进行循环迭代.问题是在循环迭代中我需要从串口获取数据,验证它并进入下一次迭代.我如何才能做到这一点?

I'm using Serial Port to get data from device in for loop iteration. The problem is in loop iteration i need to get data from serial port, validate it and going to the next iteration. How i can achieved this?

这是我的代码:

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 线程并使我的应用程序变得迟钝.任何人都可以给我一些想法吗?提前致谢.

but it seems blocked UI thread and make my application solaggy. Anyone can give me some idea? Thanks in advance.

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");
            }
        } 
    }

推荐答案

谁能给我一些想法?

Anyone can give me some idea?

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

You can use async/await in your code not to block your UI by writing an extension method like below. Usage would be:

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

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

}

这里的关键字是使用 TaskCompletionSource 类与您的事件...

The keyword here is using TaskCompletionSource class with your events...

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;
    }
}

这篇关于C# 等待直到收到数据并进入下一次迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆