c# - C# 中的多个串行端口/使用列表 <> 时出现问题

标签 c# .net serial-port virtual-serial-port

我有一个系统,它将“at”命令发送到串行端口并在消息框中显示返回结果。 但我需要在所有可用的串行端口中执行此操作。所以我创建了一个列表,并在其中添加了所有端口。 我设法发送命令,但无法继续其余代码来捕获返回,因为我在处理列表时遇到问题。我是C#初学者。 下面是我当前的代码。 被注释掉的部分是我正在努力继续的部分。 这部分属于旧代码(当时只是一个串口)。

public partial class Form1 : Form
    {
        List<SerialPort> serialPort = new List<SerialPort>();

        // delegate is used to write to a UI control from a non-UI thread
        private delegate void SetTextDeleg(string text);

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var portNames = SerialPort.GetPortNames();
            foreach (var port in portNames) {
                SerialPort sp;
                sp = new SerialPort(port, 19200, Parity.None, 8, StopBits.One);
                sp.Handshake = Handshake.None;
                //sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
                sp.ReadTimeout = 500;
                sp.WriteTimeout = 500;

                serialPort.Add(sp);
                listPorts.Items.Add(port);
            }
        }

        private void listPorts_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            foreach (var sp in serialPort) {
                // Open port
                try
                {
                    if (!sp.IsOpen)
                        sp.Open();

                    MessageBox.Show(sp.PortName + " aberto!");
                    sp.Write("at\r\n");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error opening/writing to serial port :: " + ex.Message, "Error!");
                }
            }
        }

        /* HELP START

        void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(500);
            string data = sp.ReadLine();
            this.BeginInvoke(new SetTextDeleg(si_DataReceived), new object[] { data });
        }

        private void si_DataReceived(string data)
        {
            String retorno = data.Trim();
            MessageBox.Show(retorno);
            // Fecha a porta após pegar o retorno
            sp.Close();
        }

        HELP END */

    }

要放置什么“sp.ReadLine ();”和'sp.Close();'? 由于列表,我不知道这样做<>

最佳答案

最简单的方法是使用 lambda 表达式来捕获您正在使用的端口。 lambda 表达式是一种“内联”构建委托(delegate)的方法,并且能够使用您在其中声明它的方法中的局部变量。

例如:

foreach (var port in portNames)
{
    // Object initializer to simplify setting properties
    SerialPort sp = new SerialPort(port, 19200, Parity.None, 8, StopBits.One)
    {
        Handshake = Hanshake.None,
        ReadTimeout = 500,
        WriteTimeout = 500
    };
    sp.DataReceived += (sender, args) =>
    {
        Thread.Sleep(500); // Not sure you need this...
        string data = sp.ReadLine();
        Action action = () => {
            MessageBox.Show(data.Trim());
            sp.Close();
        };
        BeginInvoke(action);
    };
    serialPort.Add(sp);
    listPorts.Items.Add(port);
}

关于此的一些注意事项:

  • 仅因为已收到一些数据并不意味着整行已收到,因此 ReadLine 可能仍会阻塞
  • 如果您需要显示消息框,则可能不需要Control.BeginInvoke。 (如果您需要在此处执行更多操作,您可能希望将大部分代码提取到一个仅接受字符串的单独方法中,然后创建一个调用该方法的操作。)
  • 您确定要在收到第一行后立即关闭串行端口吗?

关于c# - C# 中的多个串行端口/使用列表 <> 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17519760/

相关文章:

c# - 操作 HTML 文件

c# - 关闭一个表单然后调用另一个

c# - 有没有办法绑定(bind)到 Keyboard.FocusedElement?

serial-port - 如何比较 Serial.read() 中的字符串?

javascript - 我如何编码/解码这个专有校验和(Athena 16C PID Controller )?

C# 泛型和抽象工厂模式 - 或者做类似事情的某种方式

c# - 在 MonoDevelop 中学习 C# 有什么缺点吗?

.net - Windows 窗体应用程序是否忙于等待用户输入?

c# - NHibernate.Linq 1.0 GA Provider 生产就绪了吗

android - 与 Windows Phone 8 的串行通信