我编写了模拟寻路算法的应用程序。我可以运行算法或步骤(如调试)。但是当我运行算法时,我无法在算法完成之前绘制任何更改。
private void menu_run_Click(object sender, EventArgs e)
{
algorithm.Reset();
while (algorithm.status == Algorithm.Status.Searching )
{
algorithm.MakeStep();
if (this.speed != 0) System.Threading.Thread.Sleep(this.speed);
drawing_area.Invalidate();
}
}
我想这是因为我在一个周期内完成所有操作,系统无法处理我触发的新消息(事件)。
那么我应该如何更改代码以便能够在每次迭代后重绘更改?
答案 0 :(得分:1)
有很多不同的方法可以做到这一点。
可以说,最简单的方法是在表单上使用System.Windows.Forms.Timer
对象,而不是在无限循环中调用Sleep()
。
Interval
属性设置为this.speed
。Enabled
属性设置为true
。Tick
活动。处理程序看起来像这样:
private void OnTimerTick(object sender, EventArgs e)
{
if (algorithm.Status == Algorithm.Status.Searching)
{
algorithm.MakeStep();
drawing_area.Invalidate();
}
}
您可能需要稍微重新排列控制逻辑(算法启动和停止的位置)。如果有帮助,您可以使用计时器的Enabled
属性。
另一种解决方案是创建一个带有后台线程的对象,该算法在算法运行时会引发周期性事件,并且表单会订阅这些事件并相应地重绘(不要忘记在事件上使用Invoke
因为它们将来自非GUI线程。)
还有BackgroundWorker
您可以将其作为第三种选择。但我认为计时器对你来说最简单。