DoEvents()挂起

时间:2012-07-20 17:08:57

标签: c# .net frameworks doevents

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

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


首先,我知道这个问题,因为之前已经提出了一个普遍的概念 - 我(希望)有一个特定的变体要问。我也将开始说我理解使用Application.DoEvents()的具体原因并且尽可能地向所有人保证我们尽可能避免它,并且让多个线程解决问题(没有应用程序) .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上讨论它是否只是禁忌?再说一遍,我对这个论坛比较陌生,试图理解这里的礼仪。感谢。

1 个答案:

答案 0 :(得分:2)

假设利用其他[后台]线程执行此任务是错误的,这是不正确的。如果你想追求Application.DoEvents这条路很好。我不会坐在这里告诉你你不能使用它,但你至少应该考虑不使用它作为一种可能的选择。正如您所说,您正在做的是更新大量不同的UI元素。您没有执行单个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将保持响应。

相关问题