Application.DoEvents()可以在c#中使用吗?

这个函数是一种让GUI赶上应用程序其余部分的方法吗,就像VB6的DoEvents一样?


当前回答

应用程序。如果在消息队列中放入图形处理以外的内容,DoEvents可能会产生问题。

它可以用于更新进度条,并在MainForm构造和加载等过程中通知用户进度(如果这需要一段时间)。

In a recent application I've made, I used DoEvents to update some labels on a Loading Screen every time a block of code is executed in the constructor of my MainForm. The UI thread was, in this case, occupied with sending an email on a SMTP server that didn't support SendAsync() calls. I could probably have created a different thread with Begin() and End() methods and called a Send() from their, but that method is error-prone and I would prefer the Main Form of my application not throwing exceptions during construction.

其他回答

根据我的经验,我建议在。net中使用DoEvents时要非常谨慎。当在包含DataGridViews的TabControl中使用DoEvents时,我经历了一些非常奇怪的结果。另一方面,如果你所处理的只是一个带有进度条的小表单,那么它可能是OK的。

底线是:如果要使用DoEvents,那么在部署应用程序之前需要彻底测试它。

应用程序。如果在消息队列中放入图形处理以外的内容,DoEvents可能会产生问题。

它可以用于更新进度条,并在MainForm构造和加载等过程中通知用户进度(如果这需要一段时间)。

In a recent application I've made, I used DoEvents to update some labels on a Loading Screen every time a block of code is executed in the constructor of my MainForm. The UI thread was, in this case, occupied with sending an email on a SMTP server that didn't support SendAsync() calls. I could probably have created a different thread with Begin() and End() methods and called a Send() from their, but that method is error-prone and I would prefer the Main Form of my application not throwing exceptions during construction.

Yes, there is a static DoEvents method in the Application class in the System.Windows.Forms namespace. System.Windows.Forms.Application.DoEvents() can be used to process the messages waiting in the queue on the UI thread when performing a long-running task in the UI thread. This has the benefit of making the UI seem more responsive and not "locked up" while a long task is running. However, this is almost always NOT the best way to do things. According to Microsoft calling DoEvents "...causes the current thread to be suspended while all waiting window messages are processed." If an event is triggered there is a potential for unexpected and intermittent bugs that are difficult to track down. If you have an extensive task it is far better to do it in a separate thread. Running long tasks in a separate thread allows them to be processed without interfering with the UI continuing to run smoothly. Look here for more details.

下面是如何使用DoEvents的示例;请注意,微软也提供了使用它的警告。

Yes.

但是,如果您需要使用应用程序。DoEvents,这主要是一个糟糕的应用程序设计的指示。也许你想在一个单独的线程中做一些工作?

DoEvents确实允许用户单击或键入并触发其他事件,后台线程是一种更好的方法。

但是,在某些情况下,您可能会遇到需要刷新事件消息的问题。我遇到了一个问题,在RichTextBox控件忽略ScrollToCaret()方法时,该控件在队列中有消息要处理。

下面的代码在执行DoEvents时阻塞所有用户输入:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Integrative.Desktop.Common
{
    static class NativeMethods
    {
        #region Block input

        [DllImport("user32.dll", EntryPoint = "BlockInput")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool BlockInput([MarshalAs(UnmanagedType.Bool)] bool fBlockIt);

        public static void HoldUser()
        {
            BlockInput(true);
        }

        public static void ReleaseUser()
        {
            BlockInput(false);
        }

        public static void DoEventsBlockingInput()
        {
            HoldUser();
            Application.DoEvents();
            ReleaseUser();
        }

        #endregion
    }
}