调用调度程序和执行之间的时间很长

发布于 2024-10-09 21:24:20 字数 1576 浏览 6 评论 0原文

如果这是一个愚蠢的问题,我事先道歉。我的职业是一名嵌入式 C 程序员,C# 对我来说相对较新。

我有一个应用程序,基本上可以归结为以下内容:一个线程轮询外部接口(如果有人感兴趣,则为profibus),当输入数据更改时,会引发一个事件并处理新数据。 由于我需要更新的数据使用数据绑定,因此我调用调度程序。此设置可以正常工作数百万次,但有时需要长达 6 秒的时间才能执行委托中的代码。由于没有其他线程,我看不出任何原因。 我使用以下事件处理程序。 Container 是对该类进行数据绑定的 TabItem 的引用。

public void newSlave_InputChanged(object sender, InputChangedEventArgs e)
    {
        DateTime beforeDisp = DateTime.Now;
        Container.Dispatcher.Invoke(DispatcherPriority.Send, (Action)delegate()
        {
            DateTime afterDisp = DateTime.Now;
            if (afterDisp.Subtract(beforeDisp).TotalSeconds > 1)
            {
                /* Breakpoint here to detect the problem */               
            }
            /* Do the work I need to do */           

        }
    );
    }

轮询外部接口的线程基本上看起来像这样:

void monitorSlaves()
    {
        while (true)
        {
            if (cardOnline)
            {
                foreach (slave slv in slaves)
                {
                    /* get the data */
                        if (dataChanged)
                        {
                            /* raise event */
                        }
                    }
                }
                Console.WriteLine(string.Format("{0}: Monitor slaves", DateTime.Now));
            }
            Thread.Sleep(200);
        }
    }

我添加了打印以查看在调度程序“挂起”时该线程是否仍在运行。事实证明,事实并非如此。我不知道程序在调用和执行之间的几秒钟内正在做什么,因为据我所知没有其他线程在运行。不幸的是,我没有 Visual Studio 2010 Ultimate 许可证,因此我无法使用 intellitrace 来回溯运行的内容。

任何意见都将受到高度赞赏。

I apologize beforehand if this is a stupid question. I am an embedded C programmer by profession and C# is relatively new to me.

I have an application which basically boils down to the following: One thread which polls an external interface (profibus in case anyone is interested), when the input data changes an event is raised and the new data is handled.
Since the data I need to update uses databinding I invoke the dispatcher. This setup works properly millions of times, but sometimes it takes up to 6 seconds before the code in the delegate is executed. Since there are no other threads, I can not see any reason for this.
I use the following event handler. Container is a reference to the TabItem to which the class is databound.

public void newSlave_InputChanged(object sender, InputChangedEventArgs e)
    {
        DateTime beforeDisp = DateTime.Now;
        Container.Dispatcher.Invoke(DispatcherPriority.Send, (Action)delegate()
        {
            DateTime afterDisp = DateTime.Now;
            if (afterDisp.Subtract(beforeDisp).TotalSeconds > 1)
            {
                /* Breakpoint here to detect the problem */               
            }
            /* Do the work I need to do */           

        }
    );
    }

The thread polling the external interface basically look something like this:

void monitorSlaves()
    {
        while (true)
        {
            if (cardOnline)
            {
                foreach (slave slv in slaves)
                {
                    /* get the data */
                        if (dataChanged)
                        {
                            /* raise event */
                        }
                    }
                }
                Console.WriteLine(string.Format("{0}: Monitor slaves", DateTime.Now));
            }
            Thread.Sleep(200);
        }
    }

I have added the print to see if this thread is still running while the dispatcher "hangs". As it turns out, it does not. I have no idea what the program is doing in the seconds in between the invocation and the execution, since there are no other threads running as far as I know. Unfortunately I do not have a visual studio 2010 ultimate license, so I cannot use intellitrace to backtrace what ran.

Any input is greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

红尘作伴 2024-10-16 21:24:20

使用 thread.sleep 通常是不好的做法,您可能会冻结整个 UI 线程,从而导致无法正确调用 Dispatcher。我建议使用 DispatcherTimer 代替

using thread.sleep is generally bad practice, you might be freezing the entire UI thread so that the Dispatcher is not being called properly. I recommend using a DispatcherTimer instead

爱,才寂寞 2024-10-16 21:24:20

您确定您确实看到了输入吗?

一个可能的问题是接口卡 DLL 没有及时向您报告输入。

另一个可能的问题是 UI 线程太忙而无法运行您的委托。然而,6 秒的无响应时间很长

您可以添加简单的跟踪来确定原因。只需调用 Trace.TraceInformation 即可在发布模式下记录简单字符串。然后下载DebugView,它可以显示那些跟踪消息。您还可以设置 DebugView 来为它们添加时间戳并将它们保存到文件中。

PS 巧合的是,我是一名 .NET 开发人员,现在正在研究嵌入式固件。 :)

Are you sure that you're seeing the input when you think you are?

One possible problem is that the interface card DLL is not reporting the input to you in a timely manner.

Another possible problem is that the UI thread is too busy to run your delegate. However, 6 seconds is a long time to be unresponsive.

You can add simple tracing to determine the cause. Just call Trace.TraceInformation to log simple strings in Release mode. Then download DebugView, which can display those trace messages. You can also set up DebugView to timestamp them and save them to a file.

P.S. Coincidentally, I'm a .NET developer who is now working on embedded firmware. :)

瑕疵 2024-10-16 21:24:20

我敢打赌,延迟是因为垃圾收集器正在收集您创建的一堆小对象。运行 perfmon 并观察所有集合。

I bet the delay because of garbage collector is gathering bunch of small objects which you created. run perfmon and watch all the collection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文