Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do DoEvents()'s in C# actually do?

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

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.

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 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.

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?

like image 527
user316117 Avatar asked Nov 26 '14 16:11

user316117


People also ask

What is the purpose of the DoEvents command?

DoEvents is most useful for simple things like allowing a user to cancel a process after it has started, for example a search for a file. For long-running processes, yielding to the processor is better accomplished by using a Timer or delegating the task to an ActiveX EXE component.

What is DoEvents?

The DoEvents function returns an Integer representing the number of open forms in stand-alone versions of Visual Basic, such as Visual Basic, Professional Edition. DoEvents returns zero in all other applications. DoEvents passes control to the operating system.

How do I use DoEvents in Excel VBA?

Excel VBA DoEvents – Example #2Step 1: Write the subprocedure of VBA DoEvents as shown below. Step 2: Directly open a For-next loop without defining a variable. Step 3: Choose a number range we will see running. Let the range be 1 to 20000 same as example-1.

Do events in VB net?

DoEvents method has the same behavior as the DoEvents method. When you run a Windows Forms application, it creates a new form, which then waits for events to be handled. Each time the form handles an event, such as a button click, it processes all the code associated with that event. All other events wait in the queue.


2 Answers

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.

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.

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

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.

like image 184
Servy Avatar answered Sep 30 '22 16:09

Servy


VB6 DoEvents suspends processing of the current procedure (which is the only way this can happen), processes all messages in the application message queue (so events may fire), thus making your procedure reentrant. It then calls Windows API function Sleep(0). Windows then does it's message stuff. At the end of it your procedure is restarted.

The good thing is that while you get the problems of multithreading, you are still single threaded, so simple code like If InProc = True then Exit Function:InProc = True:...:InProc = False:End Function will work as it can't be preempted half way through.

like image 27
noodlesstillalive Avatar answered Sep 30 '22 17:09

noodlesstillalive