0

我在 Visual Studio 2008 中的 C# 中完成所有这些工作。

我想减慢我的算法的工作速度,以便用户可以观看它的工作。GUI 上有一个可见的周期性变化,所以我Thread.Sleep在每个实例之后添加。

问题是Thread.Sleep,当设置为至少一秒时,在几个实例之后Thread.Sleep(经过几个循环)只会冻结整个 GUI 并保持这种状态直到程序完成。不是马上,但它总是会发生。多快取决于睡眠的时间长短。

我有证据表明整个程序没有冻结,它正在工作,甚至睡眠也在正确长度的暂停。但是 GUI 在某个点冻结,直到算法结束,此时它显示正确的最终状态。

如何解决这个问题?替代在某个点暂停算法?

4

4 回答 4

7

首先,不要让用户在他们考虑何时完成之前等待完成的工作。这是毫无意义。请,只是说不。

其次,您正在“休眠” UI 线程。这就是 UI 线程“锁定”的原因。UI线程不能被阻塞;如果是,则 UI 线程无法更新表单上的控件并响应系统消息。响应系统消息是UI线程的一项重要任务;不这样做会使您的应用程序看起来被系统锁定。不是什么好事。

如果您想完成此操作(请不要),只需在您开始工作时创建一个Timer ,当它Ticks时,表明它是时候停止假装工作了。

再次,请不要这样做。

于 2011-03-27T16:07:50.650 回答
4

我猜一切都用完了一个线程。用户可能通过单击按钮或类似按钮来调用此算法。这由主线程的消息队列处理。在此事件处理程序返回之前,您的应用程序的 GUI 无法更新。它需要定期抽取消息队列以保持响应。

睡眠几乎从来都不是一个好主意,在 GUI 线程中也绝对不是一个好主意。我不建议您继续使用睡眠并通过调用 Application.DoEvents 使您的 GUI 响应。

相反,您应该在后台线程中运行此算法,并在完成时向主线程发出信号。

于 2011-03-27T16:06:37.297 回答
3

您将提交一些相当常见的用户界面漏洞:

  • 不要用细节向用户发送垃圾邮件,她只对结果感兴趣
  • 不要强迫用户按照你的要求快速工作
  • 不要禁止用户在您忙碌时与您的程序进行交互。

反而:

  • 在 ListBox 之类的小工具中显示结果,以允许用户按照自己的节奏查看结果
  • 使用线程保持用户界面交互
  • 使用调试器为您自己的利益减慢时间
于 2011-03-27T16:19:47.583 回答
0

这取决于很多事情,因此很难从您所说的内容中给出具体的答案。不过,这里有一些可能相关的问题:

您是否在 UI 线程上执行此操作(例如,触发工作开始的表单按钮或 UI 事件的线程)?如果是这样,最好创建一个新线程来执行工作。

你为什么要睡觉?如果与正在进行的工作相关的状态对所有相关线程都是可用的,那么观察者能否在工作线程不休眠的情况下观察到这一点?也许工作线程可以将当前进度的指示器写入 volatile 或锁定变量(如果它大于指针大小 - 例如 int 或对象 - 则必须锁定它 - 但不是其他情况。如果未锁定,那么 volatile 将阻止缓存CPU 之间的不一致,尽管这可能不是什么大问题)。在这种情况下,您可以有一个表单计时器(.Net 中有不同的计时器具有不同的用途)检查该变量的状态并更新 UI 以反映正在完成的工作,而工作线程不需要做任何事情。最多可能是有益的Yield()有时在工作线程中,但即使这样也不太可能需要。

于 2011-03-27T16:11:11.623 回答