【问题标题】:Draw many controls quickly using async?使用异步快速绘制许多控件?
【发布时间】:2021-01-06 04:52:32
【问题描述】:

我有一个 Windows 窗体,上面有许多控件(主要是文本框和按钮)。每次我改变表单的大小时,我都会更改控件的大小和位置,以便它们很好地分布在表单上。 问题是,当我更改表单的大小时,重绘所有控件需要半秒时间。我怎样才能加快速度?

我使用System.Diagnostics.Stopwatch 对我的代码进行计时,我认为需要很长时间的部分实际上是在屏幕上绘制控件(因为我正在做的数学运算在不到一毫秒的时间内完成)。我还对其进行了优化,因此仅在必要时重绘控件。

我的一个想法是使用异步函数使用几个不同的线程来绘制控件,但我不太了解表单如何绘制控件,所以我不知道这是否可能。 This 问题似乎表明无法从另一个线程中绘制控件。 (我之前也从未使用过异步编程,并且不确定我将如何做到这一点,所以如果可能的话,任何指针都会受到赞赏)。

我的主要问题是:

  • 是否可以使用异步编程来做到这一点?
  • 还有其他/更好的方法吗?

【问题讨论】:

  • 你真的必须使用 WinForms 吗?如果您使用 WPF,您想要实现的所有目标都会自动完成。
  • @Xaver 这是一个过去的学校项目,我正在变成一个个人项目,我没有 WPF 经验。我会看一下,但根据学习曲线,它可能比它的价值更多。
  • 查看表单的SuspendLayoutResumeLayoutPerformLayout 方法。这就是它们存在的原因。您暂停,移动所有内容,恢复,然后一次性执行
  • 我试过SuspendLayoutResumeLayout 没有成功,但可能是因为我没有使用PerformLayout

标签: c# winforms asynchronous


【解决方案1】:

只有 UI 线程可以更新 UI。因此,不能使用多任务处理来加快 UI 绘制速度。

尝试在InitializeComponent(); 后面的表格中设置DoubleBuffered = true;。有时这会有所帮助。此设置通常用于减少闪烁。

您是否尝试以编程方式分发控件?您可以使用Anchor 属性让winforms 自动为您执行此操作。还有一个FlowLayoutPanel 和一个TableLayoutPanel。这些面板对于自动布局非常有用。甚至SplitContainer 也可用于布局。

如果您正在对 UI 进行更改,您还可以尝试暂停 winforms 的布局。这样可以防止 winform 进行不必要的计算和绘图。

SuspendLayout();
try {
    // TODO: Your positioning and sizing logic
} finally {
    ResumeLayout();
}

try-finally 确保 ResumeLayout 即使在出现异常的情况下也能运行,或者当您将代码块留给 return 时。

【讨论】:

  • 我会试试 DoubleBuffer。我一直在以编程方式分发它们(我正在用非线性拉伸控件做一些更有趣的事情),但我可以尝试你提到的一些方法。
猜你喜欢
  • 1970-01-01
  • 2013-07-10
  • 1970-01-01
  • 2018-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-07
  • 2012-02-04
相关资源
最近更新 更多