473,385 Members | 1,569 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Bug? Events from private member object still firing after it has been set to Nothing?


I sometimes use delegates for broadcasting
"StateChanged" events, i.e. if I have multiple forms
and/or controls that need updating at the same time
as the result of a change in a global/common object,
I keep local references to this object in each UI
object, e.g.

Private WithEvents _tools As RepeatTools

and catch messages in an event handler like this:

Private Sub _tools_StateChanged(ByVal sender As Object, ByVal
e As System.EventArgs) Handles _tools.StateChanged
If Me.AcceptEvents Then
Try
DisplayProperties(sender)
Finally
Me.EnableEvents()
End Try
End If
End Sub

In the past, I have had problems with _tools_StateChanged
events still firing after a form has been closed - as if parts of
the form is still alive somewhere. Of course, once the event
fires and code attempts to access the now disposed controls
on the form, an exception is thrown.

Until now, I have solved this by adding something like this:

Private Sub frmRepeatPreview_FormClosing(ByVal sender As
Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles
Me.FormClosing
_tools = Nothing
End Sub

to ensure that _tools would no longer fire any events in that
form.

HOWEVER: Now I have encountered a situation where
_tools_StateChanged is firing even though _tools has been
set to Nothing, i.e. to fix it, I had to insert a "sentinel":

Private Sub _tools_StateChanged(ByVal sender As Object, ByVal
e As System.EventArgs) Handles _tools.StateChanged
If _tools Is Nothing Then
Return '<<<<<< Yes, we actually end up here!
End If

If Me.AcceptEvents Then
Try
DisplayProperties(sender)
Finally
Me.EnableEvents()
End Try
End If

End Sub

And now everything works, but I have plenty of code like
this without such a check and I am concerned that something
else might fail someday, so rather than hunt through my code
to apply the same fix everywhere, could someone please explain
to me what it is I do not understand and what I need to do to
ensure that such delegates stop firing events?

TIA,

Joergen Bech

Mar 27 '08 #1
4 2018
Hello Joergen,

Not knowing for certain how things work under the covers, this may be incorrect.

It is simply an calculated guess.

I do not know how handles works internally but let us suppose that it Translates
to an AddHandler call early on in the construction of the object.

We can then suppose that since the handler is hooked up to the instance of
the object then your setting your reference to nothing does not allow the
object to be disposed and so it remains able to generate events.

If I am correct, you could replace your Handles with an addhandler call and
call remove handler when you set _tools = nothing.

You might be able to call removehandler anyway asthough you had called addhandlerwhich
might disconnect the handles keyword.

As I say all of this is (slightly calculated) guesswork.

Perhaps it will help.

--
Rory
Mar 27 '08 #2
Hi Joergen,

Just reading the responses to your post: seems there's a lot of confusion
out there as to what WithEvents and declarative event handling in VB does.
Hopefully this will shed some light upon that for the other folks here.....

When you declare a field as WithEvents, VB actually creates a Property with
that name, and a backing field with the same name prefixed by an
underscore... in this case _tools would be the property name and it would
have a backing field __tools. In the property Set, if __tools is not
nothing, then any events declared declaratively via the Handles statement
will be unwired for the reference. (RemoveHandler), and if the new value is
not nothing, then the events will be wired up.

So given this, your setting _tools = Nothing will unwire the event handlers.
If however you wrote __tools = Nothing, you would not unwire the event
handlers, and in fact you would prevent VB from being able to unwire. The
extra _ can be an un-doing of the best of code ;)

You also may be experiencing race conditions in that even though you have
attempted to unwire, an event invocation may already be queued. This is
unlikely, but if it is just one extra event immediately after the form is
closed, it can happen.



"Joergen Bech" <jb***@post1.tele.dkwrote in message
news:g8********************************@4ax.com...
>
I sometimes use delegates for broadcasting
"StateChanged" events, i.e. if I have multiple forms
and/or controls that need updating at the same time
as the result of a change in a global/common object,
I keep local references to this object in each UI
object, e.g.

Private WithEvents _tools As RepeatTools

and catch messages in an event handler like this:

Private Sub _tools_StateChanged(ByVal sender As Object, ByVal
e As System.EventArgs) Handles _tools.StateChanged
If Me.AcceptEvents Then
Try
DisplayProperties(sender)
Finally
Me.EnableEvents()
End Try
End If
End Sub

In the past, I have had problems with _tools_StateChanged
events still firing after a form has been closed - as if parts of
the form is still alive somewhere. Of course, once the event
fires and code attempts to access the now disposed controls
on the form, an exception is thrown.

Until now, I have solved this by adding something like this:

Private Sub frmRepeatPreview_FormClosing(ByVal sender As
Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles
Me.FormClosing
_tools = Nothing
End Sub

to ensure that _tools would no longer fire any events in that
form.

HOWEVER: Now I have encountered a situation where
_tools_StateChanged is firing even though _tools has been
set to Nothing, i.e. to fix it, I had to insert a "sentinel":

Private Sub _tools_StateChanged(ByVal sender As Object, ByVal
e As System.EventArgs) Handles _tools.StateChanged
If _tools Is Nothing Then
Return '<<<<<< Yes, we actually end up here!
End If

If Me.AcceptEvents Then
Try
DisplayProperties(sender)
Finally
Me.EnableEvents()
End Try
End If

End Sub

And now everything works, but I have plenty of code like
this without such a check and I am concerned that something
else might fail someday, so rather than hunt through my code
to apply the same fix everywhere, could someone please explain
to me what it is I do not understand and what I need to do to
ensure that such delegates stop firing events?

TIA,

Joergen Bech
Mar 27 '08 #3

Thank you. I'll try the explicit Add/Remove approach and remove
the WithEvents keyword so I can control the process.

It is probably a bad idea to keep the WithEvents keyword and use
AddHandler "just in case". Unclean and unsafe in my eyes.

Regards,

Joergen Bech

On Thu, 27 Mar 2008 12:48:02 +0000 (UTC), Rory Becker
<ro********@newsgroup.nospamwrote:
>Hello Joergen,

Not knowing for certain how things work under the covers, this may be incorrect.

It is simply an calculated guess.

I do not know how handles works internally but let us suppose that it Translates
to an AddHandler call early on in the construction of the object.

We can then suppose that since the handler is hooked up to the instance of
the object then your setting your reference to nothing does not allow the
object to be disposed and so it remains able to generate events.

If I am correct, you could replace your Handles with an addhandler call and
call remove handler when you set _tools = nothing.

You might be able to call removehandler anyway asthough you had called addhandlerwhich
might disconnect the handles keyword.

As I say all of this is (slightly calculated) guesswork.

Perhaps it will help.
Mar 27 '08 #4

On Fri, 28 Mar 2008 00:47:26 +1100, "Bill McCarthy" <Bi**@NOSPAM.com>
wrote:
>Hi Joergen,

Just reading the responses to your post: seems there's a lot of confusion
out there as to what WithEvents and declarative event handling in VB does.
Hopefully this will shed some light upon that for the other folks here.....

When you declare a field as WithEvents, VB actually creates a Property with
that name, and a backing field with the same name prefixed by an
underscore... in this case _tools would be the property name and it would
have a backing field __tools. In the property Set, if __tools is not
nothing, then any events declared declaratively via the Handles statement
will be unwired for the reference. (RemoveHandler), and if the new value is
not nothing, then the events will be wired up.
I took a closer look using Reflector and you are right (which I don't
have to tell you). For others reading this thread, it looks like this:

Private Overridable Property _tools As RepeatTools
Get
Return Me.__tools
End Get
Set(ByVal WithEventsValue As RepeatTools)
If (Not Me.__tools Is Nothing) Then
RemoveHandler Me.__tools.StateChanged, New
StateChangedEventHandler(AddressOf Me._tools_StateChanged)
End If
Me.__tools = WithEventsValue
If (Not Me.__tools Is Nothing) Then
AddHandler Me.__tools.StateChanged, New
StateChangedEventHandler(AddressOf Me._tools_StateChanged)
End If
End Set
End Property

and

"_tools = Nothing"

actually becomes

"Me._tools = Nothing"

which means that the private property setter is called and the
event handler is, in fact, explicitly removed immediately, just by
using "_tools = Nothing".

This also means that removing the WithEvents keyword and adding/
removing event handlers explicitly is not going to make a bit of
difference if everything else is kept the same (i.e. if I keep the
same flow of statements/events).
>So given this, your setting _tools = Nothing will unwire the event handlers.
If however you wrote __tools = Nothing, you would not unwire the event
handlers, and in fact you would prevent VB from being able to unwire. The
extra _ can be an un-doing of the best of code ;)
I can safely say that although I start all my non-public member
variables with an underscore, there are no double underscores
in my source. I would not do such a thing :)
>You also may be experiencing race conditions in that even though you have
attempted to unwire, an event invocation may already be queued. This is
unlikely, but if it is just one extra event immediately after the form is
closed, it can happen.
You hit the nail spot on the head with that last comment.

The form/member destruction does indeed happen in response to a
StateChanged event happening for a reference to the same object
but in another form. That other form then closes the form we are
talking about, leaving a queued event that insists on firing in
limbo.

My original "sentinel" solution takes care of the problem, but
the proper solution would be to take care of the architectural flaw
that allows this to happen.

All my fault.

Regards,

Joergen Bech

Mar 27 '08 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: JPRoot | last post by:
Hi I use the following syntax to have events inherited from base to child classes which works nicely (virtual and override keyword on events). But I am wondering if it is a "supported" way of using...
1
by: John Martin | last post by:
I've made an .NET application where the contents of a datagrid (dgr1) is changed when the user changes the selection in a drop-down list (drd1). This has works fine as a beginning. Then I want to...
1
by: Rick | last post by:
Hello all, I hope all is well with you. I am having a seriously difficult time with this problem. Allow me to set up the problem. I have a System.Web.UI.Page with the following controls...
1
by: Earl Teigrob | last post by:
PROBLEM: When a user control is loaded into a PlaceHolder control more than once, the events do not fire on the first click of a control on the dynamically loaded user control. In other words, the...
24
by: ej1002 | last post by:
Hi I have developed a Windows Application(C# Windows Form) which will get the IFrame Source of the page it is navigating using Webbrowser Control. Now I want do this in ASP.Net web application(C#...
3
by: Mike | last post by:
Hi, I am adding controls dynamically in a WebForm, but none of these controls' events fire. Here is the class code I am using. I have tried so many things, but nothing works :-( namespace...
3
by: michael_vanommeren | last post by:
I have two web applications that I am working with and I am trying to do a Response.Redirect from one to the other. They are setup as separate web applications on the same IIS server. If I go...
2
by: Adam J. Schaff | last post by:
I have recently noticed an unwanted behavior that I do not know how to get rid of. To Recreate Problem: Windows Forms App with 2 forms. Form 1 has nothing on it and this code underneath: ...
3
by: JohnM | last post by:
Hi there, Are there any specific rules or best-practices I should be aware regarding events and the threads they're fired on. Object 1 can be created on thread 1 for instance and an event then...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.