How can I flush events in .Net?
-
I'm looking for something like the old Windows API FlushEvents(). I have a form which creates a COM object like such:
COMServerObject foo = new COMServerObject;
While my code waits for this singular statement to return, Windows makes my form window modal. If it takes a while for this statement to return - up to 20 seconds for .NET to give up and throw an exception - Windows queues up mouse clicks and keyboard events on my form, and then plays them back once the statement returns. This is nasty, as the user hammers away at my unresponsive window, even trying to close it. So once the statement returns, my window can suddenly fly around the screen, resize, minimize, and even close. I've tried disabling the Form while while I wait:... this.Enabled = false; COMServerObject foo = new COMServerObject; this.Enabled = true; ...
And this prevents clicks on my various buttons and menus. However, it does NOT prevent clicks on the window frame or title bar or close controls, so they still get queued up. How can I prevent these from queuing? In the old Windows API, you could call FlushEvents when you got back from a modal state, which would remove all Windows events from it's message queue. I can't find anything analogous in the .Net framework. Anybody know the proper technique, here? -
I'm looking for something like the old Windows API FlushEvents(). I have a form which creates a COM object like such:
COMServerObject foo = new COMServerObject;
While my code waits for this singular statement to return, Windows makes my form window modal. If it takes a while for this statement to return - up to 20 seconds for .NET to give up and throw an exception - Windows queues up mouse clicks and keyboard events on my form, and then plays them back once the statement returns. This is nasty, as the user hammers away at my unresponsive window, even trying to close it. So once the statement returns, my window can suddenly fly around the screen, resize, minimize, and even close. I've tried disabling the Form while while I wait:... this.Enabled = false; COMServerObject foo = new COMServerObject; this.Enabled = true; ...
And this prevents clicks on my various buttons and menus. However, it does NOT prevent clicks on the window frame or title bar or close controls, so they still get queued up. How can I prevent these from queuing? In the old Windows API, you could call FlushEvents when you got back from a modal state, which would remove all Windows events from it's message queue. I can't find anything analogous in the .Net framework. Anybody know the proper technique, here?JoeRip wrote:
Anybody know the proper technique, here?
Yeah, some asynchronous coding methods. Put the call to your COM object in background thread so the primary thread is free to handle the events.
only two letters away from being an asset
-
JoeRip wrote:
Anybody know the proper technique, here?
Yeah, some asynchronous coding methods. Put the call to your COM object in background thread so the primary thread is free to handle the events.
only two letters away from being an asset
-
With a decent design, nobody ever needs to flush events. An app is not supposed to ignore its user, if it can't or won't respond to some event, it should disable the event sources to indicate so. :|
Luc Pattyn [Forum Guidelines] [My Articles]
Happy Holidays!
-
With a decent design, nobody ever needs to flush events. An app is not supposed to ignore its user, if it can't or won't respond to some event, it should disable the event sources to indicate so. :|
Luc Pattyn [Forum Guidelines] [My Articles]
Happy Holidays!
Luc Pattyn wrote:
With a decent design, nobody ever needs to flush events.
This is an overly simplistic statement. Both the Mac OS and Win32 API's support a Flush Events procedure, which is recommended to prevent users from inadvertently losing work or destroying data. In the professional productivity applications that I was personally involved in shipping, we frequently flushed queued up events when a dialog opened, to prevent a user who was typing in word processor from overwriting original values in the dialog controls without intending to do so. While you may not agree that the situation I described needs an event flush, your statement that it is never necessary is incorrect.
-
Luc Pattyn wrote:
With a decent design, nobody ever needs to flush events.
This is an overly simplistic statement. Both the Mac OS and Win32 API's support a Flush Events procedure, which is recommended to prevent users from inadvertently losing work or destroying data. In the professional productivity applications that I was personally involved in shipping, we frequently flushed queued up events when a dialog opened, to prevent a user who was typing in word processor from overwriting original values in the dialog controls without intending to do so. While you may not agree that the situation I described needs an event flush, your statement that it is never necessary is incorrect.
Well, if you want your app to suddenly open a dialog, give it focus, and hijack all on-going user input, then you are on your own I guess. I will try and avoid ever using such an app, the way I see it the user is in control, not the app. :)
Luc Pattyn [Forum Guidelines] [My Articles]
Happy Holidays!
-
Well, if you want your app to suddenly open a dialog, give it focus, and hijack all on-going user input, then you are on your own I guess. I will try and avoid ever using such an app, the way I see it the user is in control, not the app. :)
Luc Pattyn [Forum Guidelines] [My Articles]
Happy Holidays!
-
How bizarre that you would suggest that I want this. Where are you reading that I want an application to suddenly open a dialog? Can you not simply admit that your statement was overly simplistic and incorrect?
Hrmmm I should chuck my 2c in here. Sometimes (probably due to a less than ideal architecture) you may find a whole bunch of events in your queue. The correct behaviour here is to process the events. You may choose to fast-discard keypresses and clicks - but the decision to flush the queue may cause your application to lose critical information. You could lose network connectivity change notifications, system shutdown notifications... Particularily if you are intending to have your application run on Vista - which is very very quick to detect applications not pumping their message queue, and very quick to suggest they are hanging and should be closed. So I don't think it was "overly simplistic and incorrect". It was good advice, on par with "do not call GC.Collect()". Sure - you could think up a scenario where it might be useful - but in 99% of cases you should just do it right. If you need to flush your message queue then use PInvoke to call the API function. If the framework supports this it will be in the Application or Form class. It probably doesnt, because its bad practice. HTH
Mark Churchill Director Dunn & Churchill Diamond Binding: Zero to Data Layer in 3 mins
-
Hrmmm I should chuck my 2c in here. Sometimes (probably due to a less than ideal architecture) you may find a whole bunch of events in your queue. The correct behaviour here is to process the events. You may choose to fast-discard keypresses and clicks - but the decision to flush the queue may cause your application to lose critical information. You could lose network connectivity change notifications, system shutdown notifications... Particularily if you are intending to have your application run on Vista - which is very very quick to detect applications not pumping their message queue, and very quick to suggest they are hanging and should be closed. So I don't think it was "overly simplistic and incorrect". It was good advice, on par with "do not call GC.Collect()". Sure - you could think up a scenario where it might be useful - but in 99% of cases you should just do it right. If you need to flush your message queue then use PInvoke to call the API function. If the framework supports this it will be in the Application or Form class. It probably doesnt, because its bad practice. HTH
Mark Churchill Director Dunn & Churchill Diamond Binding: Zero to Data Layer in 3 mins
All arguments aside, here's an odd behavior: Application.DoEvents() basically does the flush for me. If I do this: myForm.Enabled = false; COMServerObject foo = new COMServerObject(); Application.DoEvents(); myForm.Enabled = true; Then the queued clicks on the titlebar/closebox/minimize box, etc, do NOT get received by my app. If I reverse the order of the last two statement (enable the form, then call DoEvents()), then the messages DO get received by my app. Weird. Noted just for interest. Not advocating this as a method to flush events.