如何在递归函数内强制执行事件处理?

3
我正在用C#编写一个屏幕保护程序,慢慢地绘制Sierpinski三角形。我在递归函数内部使用Thread.Sleep来减缓绘图速度。但是我需要一种方式让用户通过移动鼠标、按键等方式退出程序。由于我的绘图函数是从表单的Paint事件处理程序中调用的,所以鼠标和键盘事件仅在整个三角形绘制完成后才会被处理,这可能需要相当长的时间。如何在递归函数运行时强制表单处理事件?(如何避免调用绘画事件引起无限循环,即调用绘画函数强制事件处理,然后再调用绘画事件等等?)
2个回答

4
您可以使用Application.DoEvents,但我不确定是否建议这样做。您可能会遇到重入问题,特别是在Paint事件中。
如果您处理Paint事件,那么似乎所有真正的工作都需要在UI线程上完成-是这样吗?
另一种方法是创建一个Bitmap并在其上绘制,而不是使用Paint事件处理程序。您可以在后台线程上执行此操作,定期创建新图像,将迄今为止绘制的图像复制到其中,绘制下一层(或其他内容),然后调度到UI线程以在UI中使用该图像。这将使主UI线程空闲以处理事件。您不需要处理Paint事件-只需拥有用于显示“到目前为止的图像”的PictureBox即可。请勿忘记在完成使用旧位图后处置它们,以避免内存问题。

+1 支持使用 Worker 方法;我赞同 Jon 的建议,不要使用 DoEvents。 - Marc Gravell

2

您可以使用后备缓冲位图,无论何时都可以计算/绘制并在Paint事件中显示它。计算可以在单独的线程中完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接