具有不同运行时的 C# While 循环

标签 c# while-loop dllimport

我在 C# 项目中使用 C++ dll 来控制科学项目的线性轴。我必须在短时间内画出轴的位置和电机电流。该轴通过 LAN 连接到我的 PC。 这是向轴发送命令的函数的 DllImport。

        [DllImport("Axis3.dll", EntryPoint = "sendCommand", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        protected static extern int m_pSendCommand(StringBuilder pcStr, StringBuilder pcRet, bool bReadLine, int iTimeOut, int iConnectionNumber);

在轴移动期间,我使用 while 循环读取位置和电机电流,并将它们写入图表列表。

private void CollectCurrentAndPositionContinous()
        {
            bool boolAxisIsMoving;
            if (AxisIsMoving(out boolAxisIsMoving, numberofController) == 0)
            {
                while (boolAxisIsMoving == true)
                {
                    if (AxisIsMoving(out boolAxisIsMoving, numberofController) != 0)
                    {
                        break;
                    }
                    CollectCurrentAndPosition();
                }
            }
        }

        private void CollectCurrentAndPosition()
        {
            string returnText;
            int errorNumber = GetPositionandCurrent(out returnText);
            if (errorNumber == 0)
            {
                if (zedDiagram.GraphPane.CurveList.Count <= 0) //make sure that the curvelist has at least one curve
                    return;

                LineItem curveCurrent = zedDiagram.GraphPane.CurveList[0] as LineItem; //Get the first CurveItem in the graph
                if (curveCurrent == null)
                { return; }


                IPointListEdit list = curveCurrent.Points as IPointListEdit; // Get the PointPairList

                if (list == null)// If this is null, it means the reference at curve.Points does not support IPointListEdit, so we won't be able to modify it
                { return; }

                string[] returnTextSplit = returnText.Split(new Char[] { ' ' }); //splits the returntext at space char
                double position = ConvertStringToDouble(returnTextSplit[0]);
                double currentA = ConvertStringToDouble(returnTextSplit[1]);
                double currentB = ConvertStringToDouble(returnTextSplit[2]);
                list.Add(position, currentA);
            }
            else
            {DisplayText(ErrorText(errorNumber));}
        }

        private int GetPositionandCurrent(out string o_returnText)
        {
            double position = 0.0;
            Venus3Wrapper.GetPosition(1, ref position, numberofController);
            int errorNumber = SendCommand("1 gc" + System.Environment.NewLine, out o_returnText, true, 50, numberofController);
            o_returnText = position.ToString(en.NumberFormat) + " " + o_returnText;
            return errorNumber;
        }

我的问题是,保存的数据之间存在很大的时间差异。两个点在 5 毫秒内保存,然后在接下来的两个点之间有 100 毫秒的间隔。我什至在它自己的线程中启动这个函数,并且每秒只重新绘制我的图表,但差距仍然存在。有人可以提示我如何获得更常规的解决方案吗?

最佳答案

我的建议是重新考虑您的设备和 PC 之间的协议(protocol)。虽然我在 OP 的代码中找不到时间方面的任何地方,但在我看来,如下所述的协议(protocol)可以解决问题。

PC->设备:开始跟踪电机/轴(无论什么)数据。
设备->PC:具有累积测量值的数据包,每个看起来都像...
{ 时间戳,值[] }。

这里有 2 个用例。 1. 保存数据供以后分析。 2. 绘制数据。如果您有高频数据,那么如果您每个数据包发送一个值(无效),或者如果您收集一堆数据点并以合理大小的数据包发送它们,那么没有人会注意到差异。

图形的 x 轴不会有通信和垃圾收集以及一般的 PC 非实时抖动,您稍后可以在分析步骤中对数据做更多的事情,因为从设备发送的时间戳是比PC端产生的时间戳更可靠。

如果您使用 TCP/IP 进行通信并且在设备端写入单个值,则数据中的“差距”也可能源于 nagle 算法。如果我没记错的话,nagle 有 100 毫秒超时...在发送之前为下一个数据包收集数据一段时间。这也可以解释您所看到的。

关于具有不同运行时的 C# While 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28396156/

相关文章:

c# - c# - web api中 "$"关键字的用途是什么

c# - 查询本地管理员组

java - 检查整数是否有重复数字。没有字符串方法或数组

language-agnostic - 循环中的最后一个元素是否值得单独处理?

dll - 如果 DLL 有 dontcopy 标志,可以在卸载程序中调用 DLL 函数吗?

c# - 如何设置 DevExpress 网格中单元格的外观?

c# - .Net 4客户端配置文件语言包检测C#

更改函数中的变量无效

c# - 如何在 Xamarin.Android 和 Xamarin.iOS 上使用 dllmap?

marshalling - 从 C#.NET 调用非托管 DLL 所需的教程