Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# UI调度缓冲?_C#_Multithreading_User Interface_Dispatch - Fatal编程技术网

C# UI调度缓冲?

C# UI调度缓冲?,c#,multithreading,user-interface,dispatch,C#,Multithreading,User Interface,Dispatch,我有一个难题。我“继承”了一个设计非常糟糕、非常复杂的系统,我正在(与我的团队)一块一块地对其进行现代化和重建。问题是,目前的系统依赖于200多名用户,由于(缺乏)设计,他们在性能方面存在重大问题。目前最有问题的问题是,大量的工作被放在UI线程上,这导致GUI挂起,直到线程被清除为止,并且消息泵可以继续。这项工作实际上需要在GUI线程上进行,因为由于其他线程上的其他计算结果,它正在更新网格中的大量字段 问题是:我没有资源专门用于重新编写这里涉及的线程模型和底层类,而这项工作的复杂性将带来重大风险

我有一个难题。我“继承”了一个设计非常糟糕、非常复杂的系统,我正在(与我的团队)一块一块地对其进行现代化和重建。问题是,目前的系统依赖于200多名用户,由于(缺乏)设计,他们在性能方面存在重大问题。目前最有问题的问题是,大量的工作被放在UI线程上,这导致GUI挂起,直到线程被清除为止,并且消息泵可以继续。这项工作实际上需要在GUI线程上进行,因为由于其他线程上的其他计算结果,它正在更新网格中的大量字段

问题是:我没有资源专门用于重新编写这里涉及的线程模型和底层类,而这项工作的复杂性将带来重大风险,这是我的客户无法接受的

我想知道是否有人对如何在不干扰currnet线程模型的情况下提高UI性能有任何建议

我最初的想法是,可能有某种方法可以在UI线程的实际调用之前放置一个“缓冲区”,以确保GUI不会过载,或者当GUI过载时,可以取消对它的调度

如有任何建议,将不胜感激

我知道这一切都不理想,但我们已经做到了,我真的想在长达一年的重写完成之前给我的用户一个更好的体验

谢谢

更新#1 这是一个winforms应用程序…很抱歉,一开始还不清楚。新代码是WPF,但这些模块是winforms

更新#2 我想我可以先尝试将大多数BeginInvoke调用更改为要调用的UI线程,引入一个序列化,有望提高UI响应能力。
这里有任何(不明显的)缺点,任何人都可以看到吗?

我不知道它是否适用于您的特定情况,但我过去也遇到过类似的情况(尽管压力可能较小),我希望我可以将或多或少的任意代码从后台线程封送到UI线程。这是在WinForms时代写的

这可能为您提供了一种风险较低的技术,使您可以在一些后台线程上抛出一些计算,并更容易地将UI更新封送到前台,而无需对线程模型进行完整的重新架构(或缺少)

关于UI的性能,有时提高速度的最佳方法是减少工作量。当我创建链接代码时,我正在开发的应用程序正在解析数百兆字节的字符串以手动咀嚼一些xml。用stringbuilders替换不可变字符串使操作从OOM故障状态在挂钟时间的5分钟内完成。然后我注意到,对于它解析的每个元素,它都会更新UI。我对代码进行了调整,每50个元素左右更新一次ui,只需几分钟。关闭所有UI更新将时间缩短到几秒钟


您是否考虑过在计算完成之前不更新UI,或者只运行进度条?另一种可能性(我不知道这有多邪恶)是将更新作为lambdas在一个字典中进行排队,该字典不受更新控制。这样,如果单个控件被多次更新,您就可以替换对值的冗余更新,例如(这假设应用程序没有直接从UI读取值来执行计算,当然,可能是这样的):()

如果您正在进行大量更新,您可以使用的和方法挂起并恢复控件中的绑定。这样,如果由于大量UI交互而无法在单独的线程中移动某些内容,您仍然可以通过不显示更新来获得一些性能提升。此外,在更新结束之前,可能会有所帮助,特别是当使用网格或其他控件时,最常见的方法是。

假设这是一个WinForms应用程序,一种相当黑客的方法是在UI线程上运行的密集工作中定期调用。这允许消息泵在逻辑中处理挂起的消息。请注意,这本身就充满了风险,例如s:

  • 所有UI事件都可能触发,这意味着您有一些类似按钮按下触发长时间运行的UI更新的情况,这些情况随后会阻止您以前使用DoEvents()完成的UI工作。这种情况的一种特别隐蔽的形式是当您“双击”按钮时,它会启动一个长时间的操作,从而生成DoEvents()它处理另一个按钮单击并旋转相同的操作,直到完成为止,然后在操作的中间将控制返回到第一个按钮点击处理器。这意味着,在UI线程上的这些“长时间运行”操作期间,您必须非常小心地允许什么UI交互。

  • 因为用户可以与UI交互,所以他们可能会使您的代码以前对不变的事物所做的假设无效。同样,限制用户所能做的事情是至关重要的,这样他们就不会使您的操作所依赖的状态无效。当然,当代码在另一个区域运行时,您也会遇到同样的问题d

  • 在VB6时代,这是一种相当常见的技术(在VB6中,多线程是非常困难的),但在现代开发中,这是不受欢迎的。它可能会让您摆脱旧应用程序的困境,但我建议使用
    //HACK
    标记它,以便将来进行清理


  • 有趣…我喜欢简单,在开始一个更复杂的解决方案(可能是对Greg想法的修改)之前尝试一下可能会很好…我有一种感觉,这种互动将导致这是一个不常见的问题。遗憾的是,这是一个危险的解决方案,正是因为