C# 如何测量UI线程使用Winforms的繁忙程度

C# 如何测量UI线程使用Winforms的繁忙程度,c#,winforms,C#,Winforms,我有一个繁忙的WinForms UI,其中包含来自多个来源的数据。因为只有UI线程可以更新UI上的控件,所以这些线程引入新的数据更新中间数据结构,UI线程读取这些数据结构,然后使用它们更新表单上的控件 为了避免并发问题,我们在读取和写入数据结构时锁定它们 应用程序中的一切都很好,但UI可能会变得非常滞后和缓慢,尤其是当我们很快收到相当多的数据时。我认为这是因为UI花费了相当多的时间等待获取锁 我知道我可以使用ProcessThread.TotalProcessorTime来衡量线程利用率,但问题

我有一个繁忙的WinForms UI,其中包含来自多个来源的数据。因为只有UI线程可以更新UI上的控件,所以这些线程引入新的数据更新中间数据结构,UI线程读取这些数据结构,然后使用它们更新表单上的控件

为了避免并发问题,我们在读取和写入数据结构时锁定它们

应用程序中的一切都很好,但UI可能会变得非常滞后和缓慢,尤其是当我们很快收到相当多的数据时。我认为这是因为UI花费了相当多的时间等待获取锁

我知道我可以使用ProcessThread.TotalProcessorTime来衡量线程利用率,但问题是,这不包括锁等待时间。因此,这是一个很好的衡量UI线程在单线程世界中有多忙的指标,但是一旦涉及到锁定,UI线程等待获取锁的时间越长,数字就会向下倾斜。正是在等待锁定的时候,用户界面才会无响应


我想,简而言之,这可以归结为Winforms应用程序中的争用度量

我看不出测量线程的CPU时间对您有什么好处。你打算做什么;如果您使用的CPU“太多”,是否停止处理?这不会解决任何问题。相反,您应该分析应用程序的瓶颈,并设计代码,使许多锁(如果不是全部的话)都是不必要的。编写到处都带有锁的惰性多线程代码非常容易,但正如您所发现的,if经常会成为性能问题。我建议将数据更新的读取放在后台,只在需要时更新UI。您需要实现一个无锁队列来处理传入的数据消息。更棒的是,您已经有了一种处理排队数据消息的机制——它被称为Windows消息泵。NET提供了
控件.BeginInvoke()
,允许您将对任意代码位的引用作为消息发送。这样做的诀窍是使您的消息成为真正的消息:也就是说,使它们成为UI可以单独作用的不可变信息。一如既往,可变共享状态是并发的敌人。