我正在使用Visual Studio 2008中的C#完成所有这些工作。
我想减慢算法的工作速度,以便用户可以观察它的工作。 GUI上有一个周期性的变化,所以我在每个实例后添加了“thread.sleep”。
问题是“thread.sleep”,当设置为至少一秒时,在“thread.sleep”的几个实例之后(在几个循环之后)简单地冻结整个GUI并保持这种方式直到程序完成。不是马上,但它总是发生。多久取决于睡眠时间。
我有证据证明整个程序没有冻结,它正在工作,即使睡眠正在暂停正确的长度。但是GUI会在某个时刻冻结,直到算法结束,此时它会显示正确的最终状态。
如何解决这个问题?替代在某一点暂停算法?
答案 0 :(得分:6)
首先,不要让用户在考虑何时完成之前等待已完成的工作。这是毫无意义。请说,不。
其次,你正在“睡觉”UI线程。这就是UI线程“锁定”的原因。无法阻止UI线程;如果是,则UI线程无法更新表单上的控件并响应系统消息。响应系统消息是UI线程的一项重要任务;如果不这样做,您的应用程序将显示为锁定系统。不是一件好事。
如果你想完成这项工作(请不要这样做),只需在开始工作时创建一个Timer,当它Ticks时,表明它有时间停止假装工作。
同样,请不要这样做。
答案 1 :(得分:4)
我猜想一切都在用完一个线程。用户可能通过单击按钮或其他类似来调用此算法。这由主线程的消息队列处理。在此事件处理程序返回之前,您的应用程序的GUI无法更新。它需要定期提取消息队列以保持响应。
睡觉几乎不是一个好主意,在GUI线程中绝对不是一个好主意。我不打算建议您继续使用sleep并通过调用Application.DoEvents来响应您的GUI。
相反,你应该在后台线程中运行这个算法,当它完成时,它应该向主线程发出信号。
答案 2 :(得分:3)
您将提交一些相当常见的用户界面bloopers:
相反:
答案 3 :(得分:0)
这取决于很多事情,所以很难从你所说的内容中给出具体的答案。不过,以下是一些可能相关的问题:
您是在UI线程上执行此操作(例如,触发工作的表单按钮或UI事件的线程)?如果是这样,最好创建一个新线程来执行工作。
你为什么要睡觉?如果所有相关线程都可以使用与正在进行的工作相关的状态,观察者是否可以在没有工作线程睡眠的情况下观察到这一点?也许工作线程可以将当前进度的指示器写入易失性或锁定变量(如果它大于指针大小则必须锁定 - 例如int或对象 - 但不是其他。如果没有锁定,那么易失性将阻止缓存CPU之间的不一致,虽然这可能不是什么大问题。在这种情况下,您可以拥有一个表单计时器(.Net中有不同的计时器用于不同目的)检查该变量的状态并更新UI以反映正在完成的工作,而工作线程不需要执行任何操作。有时候工作线程中的Yield()
可能会有所帮助,但即使这样也不太可能。