DoEvents() hanging

一个人想着一个人 提交于 2019-12-10 00:32:44

问题


How do I delete this question? I originally thought that the issue was related to DoEvents, but as it turns out, it is not. I have reposted the question here: http://goo.gl/VpAEK with a more appropriate description of the problem.

Thanks - I appreciate any guidance on how to handle this...


First, I know this question, as a general concept has been asked before - I have (hopefully) a specific variation to ask about. I will also start be saying that I understand the specific reasons not to use Application.DoEvents() and to assure everyone right up front that we avoid it whenever possible, and have multiple threads solving problems (without Application.DoEvents() involvement) throughout our app.

That being said, it is part of the framework - and I think that there are specific situations in which it has it's place.

The specific case I'm asking about is a single thread situation, with purely the UI involved, where (as I understand it), by definition - this can not be done in a background thread. More specifically, we're loading/configuring a number of UI elements in a form, that sometimes takes 1-2 seconds to complete, and I want a label to be updated during this process that indicates what is happening. There really isn't any heavy lifting/work to be done in a background thread - it's all UI.

If I don't have an Application.DoEvents() call after the 4 label text changes, the label doesn't redraw itself. If Someone can suggest an alternative that solves this differently in a purely UI, single thread environment - I'm all ears.

The problem is that, sporadically, in cases that I'm still trying to pin down, the Application.DoEvents() simply doesn't return.

I really do understand all the complaints about the DoEvents() method (most of which are totally valid!!!) and the various problems it can cause! So, ideally, without getting into a huge debate about the pros/cons of the DoEvents call (as almost every other thread on this topic seems to do) - the specific question I'm tying to answer is - can anyone think of any reason why DoEvents would simply hang? (i.e. not return)?

If you want to debate the DoEvents() call itself, there's a great description of its strengths and weaknesses here: http://goo.gl/4BtZf

  • Our users have reported that this doesn't seem to happen while they're using the app, but rather, only when they walk away from their computer for a while (screen saver involvement maybe?) We have noticed it when changing screen resolutions while remotely viewing our customer's computers.
  • We have users that insist it happens more when the app is minimized.
  • We have users that insist it happens more when the app is minimized, and they do some work in IE and/or outlook.

Internally we have been almost entirely unable to reproduce it, except this morning when I did all the above, including disabling my network connection for a minute or two and VPNing into a server for a few minutes - all while our app was minimized.

After this (literally the first time we've been able to reproduce it in house), the app hung, and when I attached to the process, it was hung on the Application.DoEvents() line. 2 line method:

label.Text = "Foo"; Application.DoEvents();

Multiple additional tests, (trying to perform the same actions) were unable to reproduce the problem.

Any suggestions? Thanks.


Edit: Is it taboo to try and get an answer to a question specifically about DoEvents? I'm relatively new to StackOverflow and I'm just a little bit confused about why I've already gotten two down votes.

I've seen this question asked many times in other threads, and the (to my eyes at least, the almost universal response is just - don't use application.DoEvents()). I specifically tried to be considerate in my original question, and to explain why we were using it in this case. At the same time, I'm specifically trying to avoid yet another discussion of why DoEvents shouldn't be used. If enough people think something is a bad idea, is it just taboo to discuss it on stackoverflow? Again, I'm relatively new to this forum and trying to understand the etiquette at play here. Thanks.


回答1:


It is incorrect to assume that it would be wrong to utilize other [background] threads to perform this task. If you want to pursue the path of Application.DoEvents that's fine. I'm not going to sit here and tell you that you mustn't use it, but you should at least consider not using it as a possible alternative. As you have said what you are doing is updating a large number of distinct UI elements. You aren't performing a single UI task, you are performing a lot (dozen, hundreds, thousands, whatever) of tasks. You also have a separate task responsible for managing all of these smaller tasks. This management of smaller tasks can be done in either the UI thread or a non-UI thread. If you do it in the UI thread then the UI is blocked until every single sub-UI action is finished. If you have a non-UI thread that acts merely as a "scheduler", adding a number of smaller UI tasks to complete then those smaller UI tasks can be performed independently and allow the UI to do...whatever...inbetween some of those tasks.

Here is an example of this:

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();
}

Will doing this be less efficient. Yes, it will be. You will be spawning off other threads/tasks, managing them, etc. However, what you get for that cost is easy and effective assurances that the UI will remain responsive.



来源:https://stackoverflow.com/questions/11583979/doevents-hanging

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!