Application.DoEvents()可以在c#中使用吗?
这个函数是一种让GUI赶上应用程序其余部分的方法吗,就像VB6的DoEvents一样?
Application.DoEvents()可以在c#中使用吗?
这个函数是一种让GUI赶上应用程序其余部分的方法吗,就像VB6的DoEvents一样?
当前回答
根据我的经验,我建议在。net中使用DoEvents时要非常谨慎。当在包含DataGridViews的TabControl中使用DoEvents时,我经历了一些非常奇怪的结果。另一方面,如果你所处理的只是一个带有进度条的小表单,那么它可能是OK的。
底线是:如果要使用DoEvents,那么在部署应用程序之前需要彻底测试它。
其他回答
根据我的经验,我建议在。net中使用DoEvents时要非常谨慎。当在包含DataGridViews的TabControl中使用DoEvents时,我经历了一些非常奇怪的结果。另一方面,如果你所处理的只是一个带有进度条的小表单,那么它可能是OK的。
底线是:如果要使用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.
Hmya, DoEvents()的持久神秘感。有很多人反对它,但没有人真正解释为什么它是“坏的”。这和“不要改变结构体”是一样的道理。嗯,为什么运行时和语言支持突变一个结构,如果这是如此糟糕?同样的原因:如果你做得不对,你就搬起石头砸自己的脚。很容易。正确地执行它需要确切地知道它做什么,在DoEvents()的情况下,这绝对不容易理解。
马上:几乎所有Windows窗体程序实际上都包含对DoEvents()的调用。它被巧妙地伪装了,但是使用了不同的名称:ShowDialog()。DoEvents()允许对话框是模态的,而不会冻结应用程序中的其他窗口。
大多数程序员在编写自己的模态循环时都希望使用DoEvents来防止用户界面冻结。它确实做到了;它分派Windows消息,并获得任何油漆请求交付。但问题是,这并不是有选择性的。它不仅发送油漆消息,还传递其他所有信息。
还有一组会引起麻烦的通知。它们来自显示器前大约3英尺的地方。例如,用户可以在调用DoEvents()的循环运行时关闭主窗口。这是可行的,用户界面消失了。但是你的代码并没有停止,它仍然在执行循环。这是不好的。非常非常糟糕。
还有更多:用户可以单击相同的菜单项或按钮,从而启动相同的循环。现在有两个嵌套循环执行DoEvents(),前一个循环暂停,新循环从头开始。这可能会起作用,但可能性很小。特别是当嵌套循环结束,挂起的循环继续时,试图完成已经完成的工作。如果没有异常爆炸,那么数据肯定被打乱了。
Back to ShowDialog(). It executes DoEvents(), but do note that it does something else. It disables all the windows in the application, other than the dialog. Now that 3-feet problem is solved, the user cannot do anything to mess up the logic. Both the close-the-window and start-the-job-again failure modes are solved. Or to put it another way, there is no way for the user to make your program run code in a different order. It will execute predictably, just like it did when you tested your code. It makes dialogs extremely annoying; who doesn't hate having a dialog active and not being able to copy and paste something from another window? But that's the price.
Which is what it takes to use DoEvents safely in your code. Setting the Enabled property of all your forms to false is a quick and efficient way to avoid problems. Of course, no programmer ever actually likes doing this. And doesn't. Which is why you shouldn't use DoEvents(). You should use threads. Even though they hand you a complete arsenal of ways to shoot your foot in colorful and inscrutable ways. But with the advantage that you only shoot your own foot; it won't (typically) let the user shoot hers.
c#和VB的下一个版本。NET将使用新的await和async关键字提供一个不同的枪。这在很小程度上是受到DoEvents和线程引起的麻烦的启发,但在很大程度上是受到WinRT的API设计的启发,它要求您在异步操作发生时保持UI的更新。比如从文件中读取。
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,这主要是一个糟糕的应用程序设计的指示。也许你想在一个单独的线程中做一些工作?