DoEvents()挂起

如何删除此问题? 我原本认为这个问题与DoEvents有关,但事实certificate,事实并非如此。 我在这里转发了这个问题: http : //goo.gl/VpAEK ,更恰当地描述了这个问题。

谢谢 – 我感谢任何关于如何处理这个问题的指导……


首先,我知道这个问题,因为之前已经提出了一个普遍的概念 – 我(希望)有一个特定的变体要问。 我也将开始说我理解使用Application.DoEvents()的具体原因,并且尽可能地向所有人保证我们尽可能避免它,并且让多个线程解决问题(没有Application.DoEvents()参与)我们的应用。

话虽如此,它框架的一部分 – 我认为有一些特定的情况,它有它的位置。

我要问的具体情况是单线程情况,纯粹涉及UI,其中(据我所知),根据定义 – 这不能在后台线程中完成。 更具体地说,我们在表单中加载/配置多个UI元素,有时需要1-2秒才能完成,我希望在此过程中更新标签以指示正在发生的事情。 在后台线程中确实没有任何繁重的工作/工作 – 这都是UI。

如果在4标签文本更改后没有Application.DoEvents()调用,则标签不会重绘自身。 如果有人可以在纯粹的UI, 单线程环境中建议一种能够解决这个问题的替代方案 – 我全都听见了。

问题是,偶尔,在我仍然试图确定的情况下,Application.DoEvents()根本不会返回。

我真的理解所有关于DoEvents()方法的抱怨(大多数都是完全有效的!!!)以及它可能导致的各种问题! 所以,理想情况下,没有进入关于DoEvents调用的优缺点的大辩论(就像这个主题的几乎所有其他线程似乎都这样) – 我想要回答的具体问题是 – 任何人都可以想到任何理由为什么DoEvents会挂起? (即不归)?

如果你想辩论DoEvents()调用本身,这里有一个很好的描述它的优点和缺点: http : //goo.gl/4BtZf

  • 我们的用户报告说,这似乎并没有在他们使用应用程序时发生,而是,只有当他们离开他们的计算机一段时间(屏幕保护程序参与可能?)我们已经注意到它在更改屏幕分辨率时远程查看我们客户的计算机。
  • 我们的用户坚持在应用程序最小化时更多地发生。
  • 我们的用户坚持认为,当应用程序最小化时,它会发生更多,并且他们在IE和/或Outlook中做一些工作。

在内部我们几乎完全无法重现它,除了今天早上我做了以上所有事情,包括禁用我的网络连接一两分钟并连接到服务器几分钟 – 所有这些都是我们的应用程序最小化。

在此之后(字面上我们第一次能够在内部重现它),应用程序挂起,当我附加到进程时,它挂在Application.DoEvents()行上。 2线法:

label.Text =“Foo”; Application.DoEvents();

多个附加测试(尝试执行相同的操作)无法重现该问题。

有什么建议? 谢谢。


编辑:是否禁忌尝试获取有关DoEvents的问题的答案? 我对StackOverflow比较陌生,我对为什么我已经获得两张选票感到有些困惑。

我已经在其他线程中多次看到这个问题,而且(至少在我看来,几乎普遍的响应只是 – 不要使用application.DoEvents())。 我特意试着在原来的问题中考虑周到,并解释为什么我们在这种情况下使用它。 与此同时,我特别试图避免再次讨论为什么不应该使用DoEvents。 如果有足够多的人认为某些事情是个坏主意,那么在stackoverflow上讨论它是否只是禁忌? 再说一遍,我对这个论坛比较陌生,试图理解这里的礼仪。 谢谢。

假设利用其他[后台]线程执行此任务是错误的是不正确的。 如果你想追求Application.DoEvents的路径,那很好。 我不会坐在这里告诉你你不能使用它,但你至少应该考虑不使用它作为一种可能的选择。 正如您所说,您正在做的是更新大量不同的UI元素。 您没有执行单个UI任务,而是执行了大量(打,数百,数千,无论如何)任务。 您还有一个单独的任务负责管理所有这些较小的任务。 可以在UI线程或非UI线程中完成对较小任务的管理。 如果您在UI线程中执行此操作,则会阻止UI,直到完成每个子UI操作。 如果你有一个非UI线程只是作为一个“调度程序”,添加一些较小的UI任务来完成那么那些较小的UI任务可以独立执行,并允许用户界面执行……无论如何…那些任务。

这是一个例子:

 private void button1_Click(object sender, EventArgs e) { Task.Factory.StartNew(() => { for (int i = 0; i < 10; i++) { Invoke(new MethodInvoker(() => updateLabel(i))); Invoke(new MethodInvoker(() => longerUITask(i))); } }); } private void longerUITask(int i) { //do databinding that will take a second or two Thread.Sleep(1000); } private void updateLabel(int i) { label1.Text = i.ToString(); } 

这样做效率会降低。 是的,它会。 您将产生其他线程/任务,管理它们等等。但是,您获得的成本是简单有效的保证,UI将保持响应。