What does DoEvents () actually do in C #?

We hired a company to convert the old VB6 library that controls some industrial machines in C #. Old VB6 code had "pause" routines consisting of sleep calls sprinkled with DoEvents so that during sleep the timer and socket events in the DLL would still be processed. DoEvents have been converted to

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

      

I am not a VB6 programmer, but my understanding is that VB6 is actually single threaded and therefore a long sleep will close everything including the timer and socket event handling.

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

      

In .Net, timer and socket events are fired on their own threads (most of my work in this converted code was trying to make it thread safe!), So it's not clear what DoEvents () is buying us for. But MSDN says

Calling this method suspends the current thread while all wait window messages are being processed.

So should we leave these DoEvents () so that other events (not timer or socket callbacks) are not blocked? Or are they overkill in the context of .Net / C #?

+8


source to share


4 answers


DoEvents

creates an additional message loop. It is just a loop that reads the message, processes it, and then reads in the next message until it receives a message that it should stop or has no messages to process. The call Application.Run

creates an initial message chain for your application. Creating additional nested message loops from one of the handlers for these messages can cause all sorts of problems , and therefore should be avoided unless you are familiar with what it does and under what circumstances you can use it correctly.

For the most part, instead of creating an additional message loop, your program should just be asynchronous. Instead of blocking the current thread for a certain period of time, you should use something like Timer

to execute the method after a certain amount of time without blocking the current thread.



In .Net, timer and socket events fire on their threads

Actually waiting for a timer to expire or getting a socket to get a response is done without using any thread. There is no thread sitting there to sleep, and operations are inherently asynchronous. This will be different for the thread that is used to execute the event handlers. Some timers will use a thread pool, some UI threads, and some are configurable and can do so. The socket will most likely use the stream's stream.

+9


source


VB6 DoEvents suspends processing of the current procedure (this is the only way it can happen), processes all messages in the application's message queue (so that events can fire), which makes your procedure repeated. Then it calls the Windows API Sleep (0) function. Windows then makes this message. At the end, its procedure is restarted.



The good thing is that as long as you run into multithreading issues, you're still single-threaded, so simple code like this If InProc = True then Exit Function:InProc = True:...:InProc = False:End Function

will work as it can't be dumped halfway through.

+4


source


Typically you don't want to use Application.DoEvents()

. A bad example of how it can be used is to make sure your cursor has changed to the wait cursor before continuing a long operation on one thread (the operation must be done on a separate thread).

 Cursor.Current = Cursors.WaitCursor;
 //Makes sure this change takes effect instead of being blocked by the next line. 
 //NOT SUPER RELIABLE
 Application.DoEvents();

 //Do long work here
 Cursor.Current = Cursors.Default;

      

In your particular case, it looks like they are trying to use it as a hack to spoof the UI to be slightly more responsive than it actually is.

0


source


*Processes all Windows messages currently in the message queue.*

http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents%28v=vs.110%29.aspx

It allows Window Forms to process any messages awaiting it from the Message Message Pump window. This way all your code waits for it half the time it is requested and then process messages and wait again.

-1


source







All Articles