Peter's Gekko

Sponsors

The Lounge

Wicked Cool Jobs

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Handles versus Addhandler , a crash course in VB.NET event support (Error 459 revisited)

In my previous post on the handling of COM events I described how I was driven into the arms of VB.NET. A VB.NET class published to COM sinks events as desired, a C# class pops up a mysterious error 459. With the help of feedback I've been delving a little deeper into this.

Events are handled by event handling methods. The way to set these in C# is by adding a delegate object to the event :

       FileSystemWatcher watcher = new FileSystemWatcher(dirName, filter);
       watcher.Created += new FileSystemEventHandler(watcher_Created);

...

       private void watcher_Created(object sender, FileSystemEventArgs e)
       {
           // Do something
       }
 

The usual way to set event handlers in VB is by using the handles keyword :

    Private WithEvents fw As New FileSystemWatcher
 

    Private Sub watcher_Created(ByVal sender As Object, ByVal e As FileSystemEventArgs) Handles fw.Created
        'Do something
    End Sub
 

The nice way about the C# syntax is that it's no problem to hook in multiple methods as event handler's to the same event:

    watcher.Created += new FileSystemEventHandler(watcher_Created);
    watcher.Created += new FileSystemEventHandler(anotherwatcher);
 

You can do the same thing, in VB.NET. In my post I admitted not knowing how to do that, Sean pointed me to the syntax to get that done using the AddHandler keyword. Instead of using handles the code could be written  as

Public Class Class1
    Private WithEvents fw As New FileSystemWatcher
    Private Sub watcher_Created(ByVal sender As Object, ByVal e As FileSystemEventArgs)
        'Do something
    End Sub

    Public Sub New()
        AddHandler fw.Created, AddressOf watcher_Created
    End Sub

End Class
 

Using this syntax I found out my VB.NET COM class started popping up the same 459 errors as the C# class. Apparently I was on to something.

Inspecting the actual code using Reflector shows that Handles and AddHandler have a subtle difference in the generated code.

The disassembly of a class using handles

constructor .ctor()

Public Sub New()
Me.fw = New FileSystemWatcher End Sub

Property setter of the object whose events are handled

<MethodImpl(MethodImplOptions.Synchronized)> _
Private Overridable Sub set_fw(ByVal WithEventsValue As FileSystemWatcher)
If (Not Me._fw Is Nothing) Then RemoveHandler Me._fw.Created, New FileSystemEventHandler(AddressOf Me.watcher_Created)
End If Me._fw = WithEventsValue If (Not Me._fw Is Nothing) Then AddHandler Me._fw.Created, New FileSystemEventHandler(AddressOf Me.watcher_Created)
End If End Sub

The disassmbly of the class when it sets the event handler in the constructor

Constructor .ctor

Public Sub New()
Me.fw = New FileSystemWatcher AddHandler Me.fw.Created, New FileSystemEventHandler(AddressOf Me.watcher_Created)
End Sub

Fw property setter

<MethodImpl(MethodImplOptions.Synchronized)> _
Private Overridable Sub set_fw(ByVal WithEventsValue As FileSystemWatcher)
If (Not Me._fw Is Nothing) Then End If Me._fw = WithEventsValue If (Not Me._fw Is Nothing) Then End If End Sub

The handles keyword does translates to an AddHandler statement. But instead of in the constructor this statement is in the property setter of the object whose event is handled and adds the delegate to the internal object instead of its property wrapper. Apparently this subtle difference is enough to provide COM with a good event support. It matches the somewhat cryptic description Although you might think you could sink the events from the implemented object, that isn't automatically the case  on msdn.

The difference between C# and VB.NET is not the language itself but the code generation, I would not know of a way to alter that.


Posted Tue, Aug 2 2005 7:56 PM by pvanooijen
Filed under:

[Advertisement]

Comments

Daniel Moth wrote re: Handles versus Addhandler , a crash course in VB.NET event support (Error 459 revisited)
on Tue, Aug 2 2005 6:39 PM
> Sean pointed me to the syntax to get that done using the AddHandler keyword

Haven't read the whole article but on the specific point on multiple handlers for a sinlge event.... in addition to the AddHandler/AddressOf approach, you can append to Handles using commas other <object>.<event> pairs.
chid wrote re: Handles versus Addhandler , a crash course in VB.NET event support (Error 459 revisited)
on Tue, Aug 2 2005 9:41 PM
Also, when you use Addhandler instead of handles, you can omit the "WithEvents" keyword.

-Mike
pvanooijen wrote re: Handles versus Addhandler , a crash course in VB.NET event support (Error 459 revisited)
on Wed, Aug 3 2005 4:20 AM
Daniel,

A handles statement containing multiple pairs is a nice extra. Missed that. But it's not dynamic, you cannot add handlers on the fly.

Mike,

OK. Point taken. But it doesn't make a difference for the generated code.

I never realized VB is a such complicated language :)
Peter's Gekko wrote Handles, AddHandler and RemoveHandler in VB.NET
on Wed, Aug 3 2005 4:37 PM
&#196;fter a crash course comes sinking in. This post is a rewrite of yesterdays one on events in VB.NET....
Peter's Gekko wrote Handles, AddHandler and RemoveHandler in VB.NET
on Thu, Aug 4 2005 4:23 AM
After a crash course comes sinking in. This post is a rewrite of yesterdays one
on events in VB.NET....
Peter's Gekko wrote Handles, AddHandler and RemoveHandler in VB.NET
on Fri, Aug 5 2005 12:07 PM
After a crash course comes sinking in. This post is a rewrite of yesterdays one
on events in VB.NET....
Peter's Gekko wrote The C# event keyword is an access modifier for delegate members
on Wed, Aug 31 2005 4:08 PM
Recently I had trouble getting COM events to work in a COM automation server written in C#. A visitor's...
Peter's Gekko wrote COM, COM events, .NET and some Delphi
on Wed, Aug 31 2005 4:08 PM
At first sight creating COM clients and servers with .NET looks like a snap. As I recently found out...
Peter's Gekko wrote The C# event keyword is an access modifier for delegate members
on Wed, Aug 31 2005 4:11 PM
Recently I had trouble getting COM events to work in a COM automation server written in C#. A visitor's...
Peter's Gekko wrote COM, COM events, .NET and some Delphi
on Wed, Aug 31 2005 4:12 PM
At first sight creating COM clients and servers with .NET looks like a snap. As I recently found out...
Peter's Gekko wrote The C# event keyword is an access modifier for delegate members
on Thu, Sep 1 2005 11:54 AM
Recently I had trouble getting COM events to work in a COM automation server written in C#. A visitor's...
Joey wrote re: Handles versus Addhandler , a crash course in VB.NET event support (Error 459 revisited)
on Thu, Sep 15 2005 2:23 PM
One other item I've had occur when I least expect it is losing the Handles on some methods (or all on a particular .vb class). It appears to be an undocumented feature in VS.NET. This behavior has never occurred using the AddHandler method.
pvanooijen wrote re: Handles versus Addhandler , a crash course in VB.NET event support (Error 459 revisited)
on Mon, Feb 6 2006 3:36 AM
Several designers in VS have the habit of "losing" an assigned handler. My biggest frustration is the web form designer.
Supposed to be better in 2005. Hasn't happened there yest...
Kent Lee wrote re: Handles versus Addhandler , a crash course in VB.NET event support (Error 459 revisited)
on Thu, May 24 2007 10:10 PM

I am using shared events and use the addHandler syntax to add the event handler for the event. However, every once in a while the events seem to get lost and my event handler doesn't see them. This doesn't happen often, but often enough to be very annoying.

Have you heard of this happening? It happened with .NET 1.1 and now happens with .NET 2.0

I'm writing in VB.NET for both .NET frameworks.

pvanooijen wrote re: Handles versus Addhandler , a crash course in VB.NET event support (Error 459 revisited)
on Tue, Jun 5 2007 3:02 AM

In 1.1. it used to be a habit of VS 2003. I wouldn't be surprised VS 2005 showing this same feature once in a while as well :/

Leeor wrote re: Handles versus Addhandler , a crash course in VB.NET event support (Error 459 revisited)
on Thu, Nov 8 2007 3:31 PM

You will find that in some instances you will need to explicitly register dynamically rendered handlers.  

Example:

AddHandler MySaveNowButton.Click, AddressOf MySaveNowEventHandler

MyPage.RegisterRequiresRaiseEvent(MySaveNowButton)

Dominique wrote re: Handles versus Addhandler , a crash course in VB.NET event support (Error 459 revisited)
on Mon, Dec 10 2007 7:04 PM

Hello,

If I add "Handles buttonHourUp, buttonMinuteUp" to my routine it fails...

Private Sub buttonUp_Click(ByVal sender As Object, ByVal e As System.EventArgs)

   If m_currentNumber = MaxValue Then

       m_currentNumber = MinValue

       m_currentTotal = 0

   Else

       m_currentNumber += 1

       m_currentTotal = m_currentNumber

   End If

   DisplayNumber()

End Sub

why?

pvanooijen wrote re: Handles versus Addhandler , a crash course in VB.NET event support (Error 459 revisited)
on Tue, Dec 11 2007 3:55 AM

Please be more precise

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Devlicio.us