C# 中的 DoEvents() 实际上做了什么? [英] What do DoEvents()'s in C# actually do?

查看:21
本文介绍了C# 中的 DoEvents() 实际上做了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们聘请了一家公司将控制一些工业机械的旧 VB6 DLL 转换为 C#.旧的 VB6 代码具有暂停"例程,其中包含带有 DoEvents 的睡眠调用,因此在睡眠时,DLL 中的计时器和套接字事件仍会得到处理.DoEvents 被转换为

We hired a company to convert an old VB6 DLL which controls some industrial machinery to C#. The old VB6 code had "pause" routines consisting of sleep calls sprinkled with DoEvents so that while sleeping, timer and socket events in the DLL would still get processed. The DoEvents were converted to

System.Windows.Forms.Application.DoEvents();

我不是 VB6 程序员,但我的理解是 VB6 实际上是单线程的,因此长时间休眠会关闭所有内容,包括计时器和套接字事件处理.

I'm not a VB6 programmer but my understanding is that VB6 is actually single-threaded and so a long sleep would shut down everything including timer and socket event handling.

当代码转换为 C# 时,暂停例程看起来像这样...

When the code was converted to C# the pause routines looked like this . . .

public static void pauseit_ms(ref int milliseconds)
{
    try
    {
        Sleep(milliseconds / 2);
        System.Windows.Forms.Application.DoEvents();
        Sleep(milliseconds / 2);
    }
    catch (Exception exc)
    {
        LogException("pauseit_ms", exc);
    }
} 

在 .Net 中,计时器和套接字事件在它们自己的线程中运行(我在这个转换后的代码中的大部分工作都是尝试使其成为线程安全的!)所以不清楚 DoEvents() 买下我们.但是 MSDN 说

In .Net, timer and socket events run in their own threads (most of my work in this converted code has been to try to make it thread-safe!) so it's not obvious what the DoEvents() buys us. But the MSDN says

调用此方法会导致当前线程暂停,同时处理所有等待窗口消息.

Calling this method causes the current thread to be suspended while all waiting window messages are processed.

那么我们是否应该将这些 DoEvents() 留在其他类型的事件(不是计时器或套接字回调)中不被阻塞?还是它们在 .Net/C# 上下文中是多余的?

So should we leave these DoEvents() in so other kinds of events (not timer or socket callbacks) aren't blocked? Or are they superfluous in a .Net/C# context?

推荐答案

DoEvents 创建一个额外的消息循环.它只是一个循环,读入一条消息,处理它,然后读入下一条消息,直到它收到一条应该停止的消息,或者没有要处理的消息.调用 Application.Run 会为您的应用程序创建初始消息循环.从这些消息的处理程序之一中创建额外的嵌套消息循环可能会导致各种问题,因此应该避免除非您非常熟悉它的作用以及在什么情况下可以正确使用它.

DoEvents creates an additional message loop. It's just a loop that reads in a message, processes it, and then reads in the next message, until it gets a message that it should stop, or has no messages to process. Calling Application.Run creates the initial message loop for your application. Creating additional nested messages loops from within one of the handlers for these messages can cause all sorts of problems and so it should be avoided unless you're intimately familiar with what it does and under what circumstances you can use it correctly.

在大多数情况下,您的程序应该是异步的,而不是创建额外的消息循环.而不是阻塞当前线程一段时间,您应该使用类似 Timer 的东西在一段时间后执行一个方法而不阻塞当前线程.

For the most part, rather than creating an additional message loop, your program should simply be asyncrhonous. Rather than blocking the current thread for a period of time, you should be using something like a Timer to execute a method after a period of time without blocking the current thread.

在 .Net 中,定时器和套接字事件在各自的线程中运行

In .Net, timer and socket events run in their own threads

实际等待计时器的时间过去,或等待套接字获得响应,是在完全不使用任何线程的情况下完成的.没有线程坐在那里睡觉,而是操作本质上是异步的.至于用于执行事件处理程序的线程,情况会有所不同.一些 Timer 将使用线程池,一些 UI 线程,还有一些是可配置的,并且两者都可以.套接字很可能只使用线程池线程.

The actual waiting for the Timer's time to elapse, or for the socket to get a response, is done without the use of any thread at all. There is no thread sitting there sleeping, rather the operations are inherently asynchronous. As for the thread that is used to execute the event handlers, that will vary. Some Timers will use a thread pool, some the UI thread, and some are configurable and can do either. The socket is likely going to just be using a thread pool thread.

这篇关于C# 中的 DoEvents() 实际上做了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆