【问题标题】:Appending strings received within a subscriber method?附加在订阅者方法中收到的字符串?
【发布时间】:2012-10-06 15:11:18
【问题描述】:

在下面的代码中,myReceivedLines 中接收到的字符串出现在与我的串口连接时(当connecttodevice 为真时)。但是,当我启动另一个命令时它们会消失(当homeall 为真时)。

我在类中添加了名为myReceivedLines 的字段,以便我可以使用方法String.Add() 来接收所有收到的反馈和发送的命令(就像程序中的控制台一样)。

为什么在发送命令时反馈消失了,如何确保所有字符串都保留在变量myReceivedLines 中? myReceivedLine 的字符串是否会因为它们发生在订阅者方法中而消失?我该如何解决?

NB:GH_DataAccess.SetDataList(Int32, IEnumerable) 是来自内核的一种方法,一个名为Grasshopper 的软件将值分配给输出(它必须在也来自此的 GH_Component.SolveInstance() 方法中使用内核),我正在使用它来可视化 myReceivedLines。

代码:

 public class SendToPrintComponent : GH_Component
    {
        //Fields
        List<string> myReceivedLines = new List<string>();
        SerialPort port;

        //subscriber method for the port.DataReceived Event
        private void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            while (sp.BytesToRead > 0)
            {
                try
                {
                    myReceivedLines.Add(sp.ReadLine());
                }
                catch (TimeoutException)
                {
                    break;
                }
            }
        }

        protected override void SolveInstance(IGH_DataAccess DA)
        {
           //Opening the port
            if (port == null)
            {
                string selectedportname = default(string);
                DA.GetData(1, ref selectedportname);
                int selectedbaudrate = default(int);
                DA.GetData(2, ref selectedbaudrate);


                //Assigning an object to the field within the SolveInstance method()
                port = new SerialPort(selectedportname, selectedbaudrate, Parity.None, 8, StopBits.One);

                //Enables the data terminal ready (dtr) signal during serial communication (handshaking)
                port.DtrEnable = true;
                port.WriteTimeout = 500;
                port.ReadTimeout = 500;
            }

            //Event Handling Method
            bool connecttodevice = default(bool);
            DA.GetData(3, ref connecttodevice);

            **if (connecttodevice == true)**
            {
                if (!port.IsOpen)
                {
                    port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                    DA.SetDataList(0, myReceivedLines);
                    port.Open();

                }
            }
            else
            if (port.IsOpen)
                {
                    port.DataReceived -= new SerialDataReceivedEventHandler(DataReceivedHandler);
                    port.Close();
                }


            if (port.IsOpen)
            {
                DA.SetData(1, "Port Open");
            }

            //If the port is open do all the rest
            if (port.IsOpen)
            {
                bool homeall = default(bool);
                DA.GetData(5, ref homeall);


                //Home all sends all the axis to the origin
                **if (homeall == true)**
                {
                    port.Write("G28" + "\n");
                    myReceivedLines.Add("G28" + "\n");
                    DA.SetDataList(2, myReceivedLines);
                }

            }
            else
            {
                DA.SetData(1, "Port Closed");
            }
        }
}

【问题讨论】:

  • 从发布的代码中看不到,您应该发布整个班级。您正在运行的线程是否发送/接收文本?如果它的线程,你将需要在更新你的字符串之前使用锁。
  • 谢谢,我编辑了答案,代码显示有问题。我不确定running thread 是什么意思。

标签: c# event-handling serial-port append grasshopper


【解决方案1】:

如果您尝试追加到字符串,我会推荐一个 StringBuilder 对象。

或者不太清晰的分辨率,使用 += 运算符,

string s = "abcd";
s+="efgh";
Console.WriteLine(s); //s prints abcdefgh

【讨论】:

  • 谢谢斯蒂芬,StringBuilder 对象是什么?
  • StringBuilder 是一种扩展字符串对象,它提供了比常规字符串对象更多的功能。它提供了诸如 .Append 之类的方法(我相信您在上面正在寻找它)以及通常在字符串上执行的许多其他有用的功能。这个网页提供了有用的例子和解释dotnetperls.com/stringbuilder
  • 谢谢斯蒂芬,我不确定StringBuilder.AppendStrings.Add 有何不同。你能澄清一下吗?非常感谢。
【解决方案2】:

首先,您的变量(myReceivedLines 和端口)不是静态的。我不确定您是否希望它们是静态的,因为我看不到您如何使用 SendToPrintComponent 类。 你能解释一下 DA.SetDataList(0, myReceivedLines);或者更好的是包含代码,因为问题可能存在......

【讨论】:

  • 感谢@DjSol,我从字段中删除了static,抱歉造成混淆。我在这里包含了几乎所有的代码。 IGH_DataAccess.SetDataList(Int32, IEnumerable) 是来自内核的一种方法,一个名为Grasshopper 的软件将值分配给输出(它必须在同样来自这个内核的GH_Component.SolveInstance() 方法中使用),我正在使用它来可视化myReceivedLines .
猜你喜欢
  • 2021-12-30
  • 2023-03-13
  • 2020-08-30
  • 1970-01-01
  • 1970-01-01
  • 2018-08-02
  • 1970-01-01
  • 2017-11-08
  • 2020-12-14
相关资源
最近更新 更多