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

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


当前回答

我见过许多使用“DoEvents-Hack”的商业应用程序。特别是当渲染开始发挥作用时,我经常看到这样的情况:

while(running)
{
    Render();
    Application.DoEvents();
}

他们都知道这种方法的害处。然而,他们使用黑客,因为他们不知道任何其他解决方案。以下是Tom Miller的博客文章中的一些方法:

Set your form to have all drawing occur in WmPaint, and do your rendering there. Before the end of the OnPaint method, make sure you do a this.Invalidate(); This will cause the OnPaint method to be fired again immediately. P/Invoke into the Win32 API and call PeekMessage/TranslateMessage/DispatchMessage. (Doevents actually does something similar, but you can do this without the extra allocations). Write your own forms class that is a small wrapper around CreateWindowEx, and give yourself complete control over the message loop. -Decide that the DoEvents method works fine for you and stick with it.

其他回答

我见过许多使用“DoEvents-Hack”的商业应用程序。特别是当渲染开始发挥作用时,我经常看到这样的情况:

while(running)
{
    Render();
    Application.DoEvents();
}

他们都知道这种方法的害处。然而,他们使用黑客,因为他们不知道任何其他解决方案。以下是Tom Miller的博客文章中的一些方法:

Set your form to have all drawing occur in WmPaint, and do your rendering there. Before the end of the OnPaint method, make sure you do a this.Invalidate(); This will cause the OnPaint method to be fired again immediately. P/Invoke into the Win32 API and call PeekMessage/TranslateMessage/DispatchMessage. (Doevents actually does something similar, but you can do this without the extra allocations). Write your own forms class that is a small wrapper around CreateWindowEx, and give yourself complete control over the message loop. -Decide that the DoEvents method works fine for you and stick with it.

应用程序。如果在消息队列中放入图形处理以外的内容,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的示例;请注意,微软也提供了使用它的警告。

可以,但这只是个黑客。

参见DoEvents邪恶吗?

直接从开发人员引用的MSDN页面:

Calling this method causes the current thread to be suspended while all waiting window messages are processed. If a message causes an event to be triggered, then other areas of your application code may execute. This can cause your application to exhibit unexpected behaviors that are difficult to debug. If you perform operations or computations that take a long time, it is often preferable to perform those operations on a new thread. For more information about asynchronous programming, see Asynchronous Programming Overview.

因此微软对它的使用提出了警告。

此外,我认为这是一个黑客,因为它的行为是不可预测的,容易产生副作用(这来自于尝试使用DoEvents而不是旋转一个新线程或使用后台工作)。

这里没有大男子主义——如果它是一个强有力的解决方案,我会全力支持它。然而,尝试在。net中使用DoEvents只会给我带来痛苦。

请查阅应用程序的MSDN文档。DoEvents方法。