By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,874 Members | 1,058 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,874 IT Pros & Developers. It's quick & easy.

Event Handling in vb.net

P: n/a
My unstanding of all VB up to and including vb6 is that an event could
not "interrupt" itself.

For instance if you had a timer event containing a msgbox then you would
only get one message.

However in vb.net you get continual messages (even setting the system
modal property).

Firstly, are these two assumptions right and if so what is the approved
way of stopping the event interrupting itself?

Secondly is this true of all events in VB.net and do I have to protect
myself when I am in any event?

TIA
Nov 21 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
Jack,
My unstanding of all VB up to and including vb6 is that an event could not
"interrupt" itself. Any Windows Event can "interrupt" itself by calling DoEvents since VB1.

In both VB.NET & VB6 MsgBox & MessageBox.Show calls the equivalent of
"DoEvents", I suspect to ensure the underlying form is properly displayed
(the Paint event is handled).

When you call DoEvents or its equivalent any event can occur a second time,
except I believe Paint and one other.
Firstly, are these two assumptions right No
and if so what is the approved way of stopping the event interrupting
itself? If I call DoEvents while processing an Event, I normally set a flag in the
event that says it is already being handled.

Something like:

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
Static beingHandled As Boolean
If beingHandled Then Exit Sub
beingHandled = True
' do work here
beingHandled = False
End Sub
Secondly is this true of all events in VB.net and do I have to protect
myself when I am in any event? You only have to protect yourself in any event that DoEvents is explicitly
or implicitly called.

FWIW there are events that are not Windows Events, these events are not
handled via the DoEvents keyword. Windows Forms applications have a message
pump (Application.Run) that causes Windows Messages in the Windows Message
Queue to be converted into Events, each event is handled inturn, unless you
call DoEvents with causes the next message in the message queue to be
converted into its respective Event. Hence if you call DoEvents explicitly
or implicitly an event can be raised a second time. This can be a source of
problems if DoEvents is called with in Timer Tick, ToolBar ButtonClick,
Button Click and MenuItem Click events.

Hope this helps
Jay
"Jack Russell" <ja***@norubbish.tpg.com.au> wrote in message
news:%2****************@tk2msftngp13.phx.gbl... My unstanding of all VB up to and including vb6 is that an event could not
"interrupt" itself.

For instance if you had a timer event containing a msgbox then you would
only get one message.

However in vb.net you get continual messages (even setting the system
modal property).

Firstly, are these two assumptions right and if so what is the approved
way of stopping the event interrupting itself?

Secondly is this true of all events in VB.net and do I have to protect
myself when I am in any event?

TIA

Nov 21 '05 #2

P: n/a
Doh!
Depending on the nature of the event processing a Try/Finally might be
beneficial in the Timer.Tick event
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
Static beingHandled As Boolean
If beingHandled Then Exit Sub Try beingHandled = True
' do work here Finally beingHandled = False End Try End Sub
As the Finally will ensure that the beingHandled flag is turned off,
especially important if you are using a Global Exception handler.

Hope this helps
Jay

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:OM*************@TK2MSFTNGP10.phx.gbl... Jack,
My unstanding of all VB up to and including vb6 is that an event could
not "interrupt" itself.

Any Windows Event can "interrupt" itself by calling DoEvents since VB1.

In both VB.NET & VB6 MsgBox & MessageBox.Show calls the equivalent of
"DoEvents", I suspect to ensure the underlying form is properly displayed
(the Paint event is handled).

When you call DoEvents or its equivalent any event can occur a second
time, except I believe Paint and one other.
Firstly, are these two assumptions right

No
and if so what is the approved way of stopping the event interrupting
itself?

If I call DoEvents while processing an Event, I normally set a flag in the
event that says it is already being handled.

Something like:

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
Static beingHandled As Boolean
If beingHandled Then Exit Sub
beingHandled = True
' do work here
beingHandled = False
End Sub
Secondly is this true of all events in VB.net and do I have to protect
myself when I am in any event?

You only have to protect yourself in any event that DoEvents is explicitly
or implicitly called.

FWIW there are events that are not Windows Events, these events are not
handled via the DoEvents keyword. Windows Forms applications have a
message pump (Application.Run) that causes Windows Messages in the Windows
Message Queue to be converted into Events, each event is handled inturn,
unless you call DoEvents with causes the next message in the message queue
to be converted into its respective Event. Hence if you call DoEvents
explicitly or implicitly an event can be raised a second time. This can be
a source of problems if DoEvents is called with in Timer Tick, ToolBar
ButtonClick, Button Click and MenuItem Click events.

Hope this helps
Jay
"Jack Russell" <ja***@norubbish.tpg.com.au> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
My unstanding of all VB up to and including vb6 is that an event could
not "interrupt" itself.

For instance if you had a timer event containing a msgbox then you would
only get one message.

However in vb.net you get continual messages (even setting the system
modal property).

Firstly, are these two assumptions right and if so what is the approved
way of stopping the event interrupting itself?

Secondly is this true of all events in VB.net and do I have to protect
myself when I am in any event?

TIA


Nov 21 '05 #3

P: n/a
Jay,

I read your response with great interest because I am working on an app
which will need a timer. What you are talking about, i.e. the re-entry of
the timer handler, requires two threads, right? I don't mean that the
programmer has asked for more than one thread, but that, somehow, under the
covers, Windows is using more than one thread. And if that's the case don't
you have to do something to make the setting of your beingHandled flag
atomic? Otherwise both threads could fetch and examine the beingHandled
flag before either thread sets it. How do you do the equivalent of a
critical section in .Net?

Thanks, Bob
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:OM*************@TK2MSFTNGP10.phx.gbl...
Jack,
My unstanding of all VB up to and including vb6 is that an event could not "interrupt" itself. Any Windows Event can "interrupt" itself by calling DoEvents since VB1.

In both VB.NET & VB6 MsgBox & MessageBox.Show calls the equivalent of
"DoEvents", I suspect to ensure the underlying form is properly displayed
(the Paint event is handled).

When you call DoEvents or its equivalent any event can occur a second

time, except I believe Paint and one other.
Firstly, are these two assumptions right No
and if so what is the approved way of stopping the event interrupting
itself?

If I call DoEvents while processing an Event, I normally set a flag in the
event that says it is already being handled.

Something like:

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
Static beingHandled As Boolean
If beingHandled Then Exit Sub
beingHandled = True
' do work here
beingHandled = False
End Sub
Secondly is this true of all events in VB.net and do I have to protect
myself when I am in any event?

You only have to protect yourself in any event that DoEvents is explicitly
or implicitly called.

FWIW there are events that are not Windows Events, these events are not
handled via the DoEvents keyword. Windows Forms applications have a

message pump (Application.Run) that causes Windows Messages in the Windows Message
Queue to be converted into Events, each event is handled inturn, unless you call DoEvents with causes the next message in the message queue to be
converted into its respective Event. Hence if you call DoEvents explicitly
or implicitly an event can be raised a second time. This can be a source of problems if DoEvents is called with in Timer Tick, ToolBar ButtonClick,
Button Click and MenuItem Click events.

Hope this helps
Jay
"Jack Russell" <ja***@norubbish.tpg.com.au> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
My unstanding of all VB up to and including vb6 is that an event could not "interrupt" itself.

For instance if you had a timer event containing a msgbox then you would
only get one message.

However in vb.net you get continual messages (even setting the system
modal property).

Firstly, are these two assumptions right and if so what is the approved
way of stopping the event interrupting itself?

Secondly is this true of all events in VB.net and do I have to protect
myself when I am in any event?

TIA


Nov 21 '05 #4

P: n/a
Bob,
What you are talking about, i.e. the re-entry of
the timer handler, requires two threads, right? No, there is only a single thread. The DoEvents itself (the one inside of
MsgBox in Jack's case) is causing a recursive call. Only one thread is
allowed to read the windows message queue, the thread that created the
window, so two threads do not come into play in this context.

Seeing as DoEvents & MsgBox are under full control of the developer, there
is no need to make beingHandled atomic.

In fact only the thread that creates windows controls are allowed to modify
those controls, so if you are creating multiple threads in your app, you
need to be certain to use Control.Invoke or Control.BeginInvoke &
Control.IsInvokeRequired as needed so as only the thread that created the
controls call methods on the control. (Of course other threads need to call
& are allowed to call Control.Invoke, Control.BeginInvoke, Control.EndInvoke
& Control.IsInvokeRequired :-))

That aside.
How do you do the equivalent of a
critical section in .Net? I normally use SyncLock, which is implemented in terms of
System.Threading.Monitor. SyncLock is easier, while Monitor provides more
control. I normally create a new Object (literally New Object) that is the
padlock used with SyncLock, something like:

Private m_padlock New Object

Public Sub ThreadedRoutine()
SyncLock m_padlock

' do work here

End SyncLock
End Sub

Alternatively I would consider making m_padlock static to ThreadedRoutine,
normally however I need/want padlock to be class scope (not procedure
scope).

Hope this helps
Jay

"eBob.com" <eB******@totallybogus.com> wrote in message
news:%2***************@TK2MSFTNGP11.phx.gbl... Jay,

I read your response with great interest because I am working on an app
which will need a timer. What you are talking about, i.e. the re-entry of
the timer handler, requires two threads, right? I don't mean that the
programmer has asked for more than one thread, but that, somehow, under
the
covers, Windows is using more than one thread. And if that's the case
don't
you have to do something to make the setting of your beingHandled flag
atomic? Otherwise both threads could fetch and examine the beingHandled
flag before either thread sets it. How do you do the equivalent of a
critical section in .Net?

Thanks, Bob
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:OM*************@TK2MSFTNGP10.phx.gbl...
Jack,
> My unstanding of all VB up to and including vb6 is that an event could not > "interrupt" itself.

Any Windows Event can "interrupt" itself by calling DoEvents since VB1.

In both VB.NET & VB6 MsgBox & MessageBox.Show calls the equivalent of
"DoEvents", I suspect to ensure the underlying form is properly displayed
(the Paint event is handled).

When you call DoEvents or its equivalent any event can occur a second

time,
except I believe Paint and one other.
> Firstly, are these two assumptions right

No
> and if so what is the approved way of stopping the event interrupting
> itself?

If I call DoEvents while processing an Event, I normally set a flag in
the
event that says it is already being handled.

Something like:

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
Static beingHandled As Boolean
If beingHandled Then Exit Sub
beingHandled = True
' do work here
beingHandled = False
End Sub
> Secondly is this true of all events in VB.net and do I have to protect
> myself when I am in any event?

You only have to protect yourself in any event that DoEvents is
explicitly
or implicitly called.

FWIW there are events that are not Windows Events, these events are not
handled via the DoEvents keyword. Windows Forms applications have a

message
pump (Application.Run) that causes Windows Messages in the Windows
Message
Queue to be converted into Events, each event is handled inturn, unless

you
call DoEvents with causes the next message in the message queue to be
converted into its respective Event. Hence if you call DoEvents
explicitly
or implicitly an event can be raised a second time. This can be a source

of
problems if DoEvents is called with in Timer Tick, ToolBar ButtonClick,
Button Click and MenuItem Click events.

Hope this helps
Jay
"Jack Russell" <ja***@norubbish.tpg.com.au> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
> My unstanding of all VB up to and including vb6 is that an event could not > "interrupt" itself.
>
> For instance if you had a timer event containing a msgbox then you
> would
> only get one message.
>
> However in vb.net you get continual messages (even setting the system
> modal property).
>
> Firstly, are these two assumptions right and if so what is the approved
> way of stopping the event interrupting itself?
>
> Secondly is this true of all events in VB.net and do I have to protect
> myself when I am in any event?
>
> TIA



Nov 21 '05 #5

P: n/a
Hi,

.In addition to Jay's comments. You can use Synclock to prevent
multiple procedure from changing a variable at one time.

http://msdn.microsoft.com/library/de...tmSyncLock.asp

Ken
-----------------------
"Jack Russell" <ja***@norubbish.tpg.com.au> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
My unstanding of all VB up to and including vb6 is that an event could
not "interrupt" itself.

For instance if you had a timer event containing a msgbox then you would
only get one message.

However in vb.net you get continual messages (even setting the system
modal property).

Firstly, are these two assumptions right and if so what is the approved
way of stopping the event interrupting itself?

Secondly is this true of all events in VB.net and do I have to protect
myself when I am in any event?

TIA
Nov 21 '05 #6

P: n/a
Wow! What an eye opener this thread has been, at least for this
novice VB.NETer. Thanks you Jay. The moral seems to be that you had
better know whether anything you call might call DoEvents. In fact
you had better know if anything you call might call anything which
might call DoEvents. ... etc. etc. etc. MessageBox.Show
documentation does not mention this "interesting" aspect of its use.
Are there other calls I should beware of?

I am still having trouble grasping this. If I use MB in a timer tick
event handler I sure see the effect of the DoEvents call - MBs
overlaying MBs. BUT ... when I throw up a MB all of the controls on
my form are disabled until I click the OK. I.E. clicks on a Button
or a NumericUp/Down are ignored. Ignored - not just saved up and
processed after I click on the OK button. So if the timer tick events
are getting processed why are the Button events and NumericUp/Down
events not getting processed? (Or is this what you were addressing in
your original reply to Jack Russel when you pointed out that "there
are events that are not Windows Events ...". I didn't follow all of
that.)

And another thing which is confusing me (if I can explain it) ...
In my little experiment I used MB in a timer tick handler. The
interval was set to 1 second and I got the MBs faster than I could get
rid of them. But surely the first MB was displayed before the second
timer tick ticked. So if the MB code called DoEvents before it
displayed the MB, then the second tick hadn't tocked yet and DoEvents
would not have found an event to Do. If MB is calling DoEvents while
it is waiting for me click on OK ... well ... I don't understand how
it would do anything while it is waiting? Is MB polling to see if I
have clicked the OK button instead of waiting for me to click it?

I hope that these are not dumb questions but this strikes me as a very
important topic (not to mention really interesting).

Thanks, Bob

On Fri, 1 Oct 2004 07:46:09 -0500, "Jay B. Harlow [MVP - Outlook]"
<Ja************@msn.com> wrote:
Bob,
What you are talking about, i.e. the re-entry of
the timer handler, requires two threads, right?

No, there is only a single thread. The DoEvents itself (the one inside of
MsgBox in Jack's case) is causing a recursive call. Only one thread is
allowed to read the windows message queue, the thread that created the
window, so two threads do not come into play in this context.

Seeing as DoEvents & MsgBox are under full control of the developer, there
is no need to make beingHandled atomic.

In fact only the thread that creates windows controls are allowed to modify
those controls, so if you are creating multiple threads in your app, you
need to be certain to use Control.Invoke or Control.BeginInvoke &
Control.IsInvokeRequired as needed so as only the thread that created the
controls call methods on the control. (Of course other threads need to call
& are allowed to call Control.Invoke, Control.BeginInvoke, Control.EndInvoke
& Control.IsInvokeRequired :-))

That aside.
How do you do the equivalent of a
critical section in .Net?

I normally use SyncLock, which is implemented in terms of
System.Threading.Monitor. SyncLock is easier, while Monitor provides more
control. I normally create a new Object (literally New Object) that is the
padlock used with SyncLock, something like:

Private m_padlock New Object

Public Sub ThreadedRoutine()
SyncLock m_padlock

' do work here

End SyncLock
End Sub

Alternatively I would consider making m_padlock static to ThreadedRoutine,
normally however I need/want padlock to be class scope (not procedure
scope).

Hope this helps
Jay

"eBob.com" <eB******@totallybogus.com> wrote in message
news:%2***************@TK2MSFTNGP11.phx.gbl...
Jay,

I read your response with great interest because I am working on an app
which will need a timer. What you are talking about, i.e. the re-entry of
the timer handler, requires two threads, right? I don't mean that the
programmer has asked for more than one thread, but that, somehow, under
the
covers, Windows is using more than one thread. And if that's the case
don't
you have to do something to make the setting of your beingHandled flag
atomic? Otherwise both threads could fetch and examine the beingHandled
flag before either thread sets it. How do you do the equivalent of a
critical section in .Net?

Thanks, Bob
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:OM*************@TK2MSFTNGP10.phx.gbl...
Jack,
> My unstanding of all VB up to and including vb6 is that an event could

not
> "interrupt" itself.
Any Windows Event can "interrupt" itself by calling DoEvents since VB1.

In both VB.NET & VB6 MsgBox & MessageBox.Show calls the equivalent of
"DoEvents", I suspect to ensure the underlying form is properly displayed
(the Paint event is handled).

When you call DoEvents or its equivalent any event can occur a second

time,
except I believe Paint and one other.

> Firstly, are these two assumptions right
No

> and if so what is the approved way of stopping the event interrupting
> itself?
If I call DoEvents while processing an Event, I normally set a flag in
the
event that says it is already being handled.

Something like:

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
Static beingHandled As Boolean
If beingHandled Then Exit Sub
beingHandled = True
' do work here
beingHandled = False
End Sub

> Secondly is this true of all events in VB.net and do I have to protect
> myself when I am in any event?
You only have to protect yourself in any event that DoEvents is
explicitly
or implicitly called.

FWIW there are events that are not Windows Events, these events are not
handled via the DoEvents keyword. Windows Forms applications have a

message
pump (Application.Run) that causes Windows Messages in the Windows
Message
Queue to be converted into Events, each event is handled inturn, unless

you
call DoEvents with causes the next message in the message queue to be
converted into its respective Event. Hence if you call DoEvents
explicitly
or implicitly an event can be raised a second time. This can be a source

of
problems if DoEvents is called with in Timer Tick, ToolBar ButtonClick,
Button Click and MenuItem Click events.

Hope this helps
Jay
"Jack Russell" <ja***@norubbish.tpg.com.au> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
> My unstanding of all VB up to and including vb6 is that an event could

not
> "interrupt" itself.
>
> For instance if you had a timer event containing a msgbox then you
> would
> only get one message.
>
> However in vb.net you get continual messages (even setting the system
> modal property).
>
> Firstly, are these two assumptions right and if so what is the approved
> way of stopping the event interrupting itself?
>
> Secondly is this true of all events in VB.net and do I have to protect
> myself when I am in any event?
>
> TIA



Nov 21 '05 #7

P: n/a
Jay B. Harlow [MVP - Outlook] wrote:
Jack,
My unstanding of all VB up to and including vb6 is that an event could not
"interrupt" itself.


Any Windows Event can "interrupt" itself by calling DoEvents since VB1.

In both VB.NET & VB6 MsgBox & MessageBox.Show calls the equivalent of
"DoEvents", I suspect to ensure the underlying form is properly displayed
(the Paint event is handled).

When you call DoEvents or its equivalent any event can occur a second time,
except I believe Paint and one other.

Firstly, are these two assumptions right


No

and if so what is the approved way of stopping the event interrupting
itself?


If I call DoEvents while processing an Event, I normally set a flag in the
event that says it is already being handled.

Something like:

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
Static beingHandled As Boolean
If beingHandled Then Exit Sub
beingHandled = True
' do work here
beingHandled = False
End Sub

Secondly is this true of all events in VB.net and do I have to protect
myself when I am in any event?


You only have to protect yourself in any event that DoEvents is explicitly
or implicitly called.

FWIW there are events that are not Windows Events, these events are not
handled via the DoEvents keyword. Windows Forms applications have a message
pump (Application.Run) that causes Windows Messages in the Windows Message
Queue to be converted into Events, each event is handled inturn, unless you
call DoEvents with causes the next message in the message queue to be
converted into its respective Event. Hence if you call DoEvents explicitly
or implicitly an event can be raised a second time. This can be a source of
problems if DoEvents is called with in Timer Tick, ToolBar ButtonClick,
Button Click and MenuItem Click events.

Hope this helps
Jay
"Jack Russell" <ja***@norubbish.tpg.com.au> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
My unstanding of all VB up to and including vb6 is that an event could not
"interrupt" itself.

For instance if you had a timer event containing a msgbox then you would
only get one message.

However in vb.net you get continual messages (even setting the system
modal property).

Firstly, are these two assumptions right and if so what is the approved
way of stopping the event interrupting itself?

Secondly is this true of all events in VB.net and do I have to protect
myself when I am in any event?

TIA


Thanks for the replies. You say VB6 is the same but I just tried it and
there is no second occurance, so either msgbox is different or the timer
event is different.

That piece of academia apart, how do I kow what other things contain a
hidden "do events"? Or do I protect all events. I was consdering with
the timer just disabling it at the start and re-enabling at the end.
As an old asembler programmer I can see dangers in the busy flag or
disabling as neither of these are accomplished in a single machine
instruction but I guess they will work assuming that an event cannot
interrupt itself except in the case of a "do events".
I will investigate synclock.

Nov 21 '05 #8

P: n/a
Jack,
Thanks for the replies. You say VB6 is the same but I just tried it and
there is no second occurance, so either msgbox is different or the timer
event is different. You are correct, VB6 appears to only allow the Paint event to continue to be
handled, it appears to block the Timer event. Without the Paint event being
handled your form will not redraw itself properly...
That piece of academia apart, Again, you are correct, VB6 behavior is largely academia...
how do I kow what other things contain a hidden "do events"? Or do I
protect all events. How paranoid are you? seriously?

If you are super paranoid about it, I would suggest you protect all events.

Me I only protect those routines that I know I am calling DoEvents
(explicitly) in, I rarely call DoEvents, ergo its not an issue. I do not
explicitly call MessageBox.Show from a Timer, so the fact that
MessageBox.Show allows a timer event to fire a second time is largely moot
for me. I may explicitly call MessageBox.Show within a "command" click event
(ToolBarButton Click, Button Click or MenuItem Click), seeing as
MessageBox.Show is modal, the user will not be able to click the same
ToolBar ButtonClick, Button Click or MenuItem Click event a second time, so
protecting any "command" click is moot also. Other events I would handle on
a case by case basis.

I have yet to actually come across a Windows Forms event that I
inadvertently entered a second time, hence I rarely need to protect the
event.

Note, using Synclock to protect an event wont work, as the current Thread
owns the Synclock, so when you attempt to lock the same object, you will
simply gain access to it.

Try the following, without clicking OK on the message box, you should see
multiple Timer1_Tick message boxes show up...

Private WithEvents Timer1 As System.Windows.Forms.Timer
'
'Timer1
'
Me.Timer1.Enabled = True
Me.Timer1.Interval = 4000

Private ReadOnly m_padlock As New Object

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
SyncLock m_padlock
MessageBox.Show("Timer1_Tick")
End SyncLock
End Sub

Note: I stated "I do not explicitly call MessageBox.Show from a Timer"
above, I may implicitly call MessageBox.Show, as my Global Exception
Handlers may call MessageBox.Show to display exceptions to the user, if the
Timer event happens to have an unhandled exception, then in this case I
could implicitly call MessageBox.Show. Seeing as this is an Exceptional case
(no pun intended) I'm not sure how concerned I would be with "protecting"
the Timer event from reentrancy.

Hope this helps
Jay
"Jack Russell" <ja***@norubbish.tpg.com.au> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl... Jay B. Harlow [MVP - Outlook] wrote:
Jack,
My unstanding of all VB up to and including vb6 is that an event could
not "interrupt" itself.


Any Windows Event can "interrupt" itself by calling DoEvents since VB1.

In both VB.NET & VB6 MsgBox & MessageBox.Show calls the equivalent of
"DoEvents", I suspect to ensure the underlying form is properly displayed
(the Paint event is handled).

When you call DoEvents or its equivalent any event can occur a second
time, except I believe Paint and one other.

Firstly, are these two assumptions right


No

and if so what is the approved way of stopping the event interrupting
itself?


If I call DoEvents while processing an Event, I normally set a flag in
the event that says it is already being handled.

Something like:

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
Static beingHandled As Boolean
If beingHandled Then Exit Sub
beingHandled = True
' do work here
beingHandled = False
End Sub

Secondly is this true of all events in VB.net and do I have to protect
myself when I am in any event?


You only have to protect yourself in any event that DoEvents is
explicitly or implicitly called.

FWIW there are events that are not Windows Events, these events are not
handled via the DoEvents keyword. Windows Forms applications have a
message pump (Application.Run) that causes Windows Messages in the
Windows Message Queue to be converted into Events, each event is handled
inturn, unless you call DoEvents with causes the next message in the
message queue to be converted into its respective Event. Hence if you
call DoEvents explicitly or implicitly an event can be raised a second
time. This can be a source of problems if DoEvents is called with in
Timer Tick, ToolBar ButtonClick, Button Click and MenuItem Click events.

Hope this helps
Jay
"Jack Russell" <ja***@norubbish.tpg.com.au> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
My unstanding of all VB up to and including vb6 is that an event could
not "interrupt" itself.

For instance if you had a timer event containing a msgbox then you would
only get one message.

However in vb.net you get continual messages (even setting the system
modal property).

Firstly, are these two assumptions right and if so what is the approved
way of stopping the event interrupting itself?

Secondly is this true of all events in VB.net and do I have to protect
myself when I am in any event?

TIA


Thanks for the replies. You say VB6 is the same but I just tried it and
there is no second occurance, so either msgbox is different or the timer
event is different.

That piece of academia apart, how do I kow what other things contain a
hidden "do events"? Or do I protect all events. I was consdering with the
timer just disabling it at the start and re-enabling at the end.
As an old asembler programmer I can see dangers in the busy flag or
disabling as neither of these are accomplished in a single machine
instruction but I guess they will work assuming that an event cannot
interrupt itself except in the case of a "do events".
I will investigate synclock.

Nov 21 '05 #9

P: n/a
Bob,
See my response to Jack.

Message boxes are Modal, which means that your form is "disabled" (won't
accept keyboard or mouse input) until the message box is closed. (actually
its closer to your form losses focus and the message box captures it until
closed). Ergo you Button, NumericUpDown will not receive any keyboard or
mouse input (the message box is receiving all this input & ignores it).
I really have to ask: Are developers seriously writing applications where
you are calling MessageBox.Show in the Timer.Click event? Is that a real
requirement in your apps? Why?
I can see having a Timer that fires once a second to check a database or web
resource, if the resource is not available and I needed to display a message
box, I would disable the Timer, then let the user know the problem, asking
the user if they wanted me to keep trying or not. More then likely I would
change something in the system tray or status bar of my app, which the user
could then click to see what the problem was.

Hope this helps
Jay
"eBob.com" <eB******@totallyfakeisp.com> wrote in message
news:pm********************************@4ax.com...
Wow! What an eye opener this thread has been, at least for this
novice VB.NETer. Thanks you Jay. The moral seems to be that you had
better know whether anything you call might call DoEvents. In fact
you had better know if anything you call might call anything which
might call DoEvents. ... etc. etc. etc. MessageBox.Show
documentation does not mention this "interesting" aspect of its use.
Are there other calls I should beware of?

I am still having trouble grasping this. If I use MB in a timer tick
event handler I sure see the effect of the DoEvents call - MBs
overlaying MBs. BUT ... when I throw up a MB all of the controls on
my form are disabled until I click the OK. I.E. clicks on a Button
or a NumericUp/Down are ignored. Ignored - not just saved up and
processed after I click on the OK button. So if the timer tick events
are getting processed why are the Button events and NumericUp/Down
events not getting processed? (Or is this what you were addressing in
your original reply to Jack Russel when you pointed out that "there
are events that are not Windows Events ...". I didn't follow all of
that.)

And another thing which is confusing me (if I can explain it) ...
In my little experiment I used MB in a timer tick handler. The
interval was set to 1 second and I got the MBs faster than I could get
rid of them. But surely the first MB was displayed before the second
timer tick ticked. So if the MB code called DoEvents before it
displayed the MB, then the second tick hadn't tocked yet and DoEvents
would not have found an event to Do. If MB is calling DoEvents while
it is waiting for me click on OK ... well ... I don't understand how
it would do anything while it is waiting? Is MB polling to see if I
have clicked the OK button instead of waiting for me to click it?

I hope that these are not dumb questions but this strikes me as a very
important topic (not to mention really interesting).

Thanks, Bob

<<snip>>
Nov 21 '05 #10

P: n/a
Hi Jay,

Thanks for the further explanation. It helps to know that Message Boxes are
Modal.
I really have to ask: Are developers seriously writing applications where
you are calling MessageBox.Show in the Timer.Click event? Is that a real
requirement in your apps? Why?
Not this developer! I've used MessageBox.Show twice in a Timer tick event
handler (I'm a slow learner), but now, thanks to the education you've
provided, if I ever need to in the future I'll be sure to disable additional
timer ticks while MB.S has control.

The level of my interest is due to 1) I was wondering where else DoEvents
might be lurking? (You covered this in your response to Jack.) 2) I
*really* like to understand what is going on beneath the covers. (I've done
*a*lot* of programming in assembly language [but not for x86 machines]). 3)
I've worked on operating system design - so I get into things like this.

Thanks for your patient and generous responses.

Bob
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:eD**************@TK2MSFTNGP15.phx.gbl... Bob,
See my response to Jack.

Message boxes are Modal, which means that your form is "disabled" (won't
accept keyboard or mouse input) until the message box is closed. (actually
its closer to your form losses focus and the message box captures it until
closed). Ergo you Button, NumericUpDown will not receive any keyboard or
mouse input (the message box is receiving all this input & ignores it).
I really have to ask: Are developers seriously writing applications where
you are calling MessageBox.Show in the Timer.Click event? Is that a real
requirement in your apps? Why?
I can see having a Timer that fires once a second to check a database or web resource, if the resource is not available and I needed to display a message box, I would disable the Timer, then let the user know the problem, asking
the user if they wanted me to keep trying or not. More then likely I would
change something in the system tray or status bar of my app, which the user could then click to see what the problem was.

Hope this helps
Jay
"eBob.com" <eB******@totallyfakeisp.com> wrote in message
news:pm********************************@4ax.com...
Wow! What an eye opener this thread has been, at least for this
novice VB.NETer. Thanks you Jay. The moral seems to be that you had
better know whether anything you call might call DoEvents. In fact
you had better know if anything you call might call anything which
might call DoEvents. ... etc. etc. etc. MessageBox.Show
documentation does not mention this "interesting" aspect of its use.
Are there other calls I should beware of?

I am still having trouble grasping this. If I use MB in a timer tick
event handler I sure see the effect of the DoEvents call - MBs
overlaying MBs. BUT ... when I throw up a MB all of the controls on
my form are disabled until I click the OK. I.E. clicks on a Button
or a NumericUp/Down are ignored. Ignored - not just saved up and
processed after I click on the OK button. So if the timer tick events
are getting processed why are the Button events and NumericUp/Down
events not getting processed? (Or is this what you were addressing in
your original reply to Jack Russel when you pointed out that "there
are events that are not Windows Events ...". I didn't follow all of
that.)

And another thing which is confusing me (if I can explain it) ...
In my little experiment I used MB in a timer tick handler. The
interval was set to 1 second and I got the MBs faster than I could get
rid of them. But surely the first MB was displayed before the second
timer tick ticked. So if the MB code called DoEvents before it
displayed the MB, then the second tick hadn't tocked yet and DoEvents
would not have found an event to Do. If MB is calling DoEvents while
it is waiting for me click on OK ... well ... I don't understand how
it would do anything while it is waiting? Is MB polling to see if I
have clicked the OK button instead of waiting for me to click it?

I hope that these are not dumb questions but this strikes me as a very
important topic (not to mention really interesting).

Thanks, Bob

<<snip>>

Nov 21 '05 #11

P: n/a
Jay B. Harlow [MVP - Outlook] wrote:


I really have to ask: Are developers seriously writing applications where
you are calling MessageBox.Show in the Timer.Click event? Is that a real
requirement in your apps? Why?


I have an application which drives instruments connected via serial
ports. These have to be polled, status checked etc.

In a stand alone computer I would do this in an "idle loop". However as
VB does not have such a thing (to the best of my knowledge) I have to do
it with a timer. Generally this does not require message boxes although
they are the best way to bring things to a halt when problems occur (I
also use them in debugging of course).
Any alternative methods of doing this without using timers gratefully
accepted.

And to answer your question from another messages, yes I am paranoid, 40
plus years of prgoramming such beasties makes you that way.
Nov 21 '05 #12

P: n/a
Jack,
I have an application which drives instruments connected via serial ports.
These have to be polled, status checked etc.
Any alternative methods of doing this without using timers gratefully
accepted. Sounds like a job for a separate Thread.
In a stand alone computer I would do this in an "idle loop". However as VB
does not have such a thing (to the best of my knowledge) I have to do it
with a timer. I would use a separate thread to handle the serial port, with one or more
threads doing the monitoring (these may or may not be the same as the serial
port thread), these threads would be in an "idle loop" monitoring/polling
the resource, they would use either Thread.Sleep or one of the other
synchronization objects in System.Threading to be system resource friendly.
The Main thread would be reserved for UI. The separate threads would use
Control.Invoke or Control.BeginInvoke to have information displayed to the
user. Alternative I would define a lightweight "MessageQueue" class that
utilized System.Collections.Queue & System.Threading.AutoResetEvent to allow
one thread to communicate with another thread.

FWIW: .NET Windows Forms apps have an Application.Idle event which is handy
to do stuff when you app is idle. Windows Forms will raise the
Application.Idle event when it has finished processing other pending events.
I normally update my tool bar buttons & status bar in the Application.Idle
event
they are the best way to bring things to a halt when problems occur I find throwing (context specific) Exceptions to be the "best" way to bring
things to a halt when problems occur. Especially when coupled with the
"Break into the debugger" options under "Debug - Exceptions" in VS.NET.
(I also use them in debugging of course). I rarely use MessageBoxes during debugging. I find the Debug & Trace classes
in System.Diagnostics to be far more powerful tools, in addition to
leveraging the debugging features of VS.NET. As you found out MessageBoxes
can alter the behavior of your application.

Hope this helps
Jay

"Jack Russell" <ja***@norubbish.tpg.com.au> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl... Jay B. Harlow [MVP - Outlook] wrote:


I really have to ask: Are developers seriously writing applications where
you are calling MessageBox.Show in the Timer.Click event? Is that a real
requirement in your apps? Why?


I have an application which drives instruments connected via serial ports.
These have to be polled, status checked etc.

In a stand alone computer I would do this in an "idle loop". However as VB
does not have such a thing (to the best of my knowledge) I have to do it
with a timer. Generally this does not require message boxes although they
are the best way to bring things to a halt when problems occur (I also use
them in debugging of course).
Any alternative methods of doing this without using timers gratefully
accepted.

And to answer your question from another messages, yes I am paranoid, 40
plus years of prgoramming such beasties makes you that way.

Nov 21 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.