Wrox Programmer Forums
|
General .NET For general discussion of MICROSOFT .NET topics that don't fall within any of the other .NET forum subcategories or .NET language forums.  If your question is specific to a language (C# or Visual Basic) or type of application (Windows Forms or ASP.Net) try an applicable forum category. ** PLEASE BE SPECIFIC WITH YOUR QUESTION ** When posting here, provide details regarding the Microsoft .NET language you are using and/or what type of application (Windows/Web Forms, etc) you are working in, if applicable to the question. This will help others answer the question without having to ask.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the General .NET section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old June 3rd, 2008, 06:50 AM
Authorized User
 
Join Date: Aug 2006
Posts: 41
Thanks: 1
Thanked 0 Times in 0 Posts
Default Delegate query

Hi all,
I've been playing around with writing my own event handlers and I've a query about the use of a delegate.

Basically, I've noticed you don't need to declare a delegate to handle an event, but you can delcare a public event with the same signature as a delegate (see Finished Event defined below). Can anyone explain if what I'm doing in declaring the event handler this way is incorrect or should I always use a delegate?

I'm slightly confused to what the differences are and if there's any performance/run-time differences. I've included an example below which uses both types of declaration. One just counts down and raises an event every 0.5 seconds (update - delegate declared) and then raises and finish event after 5 seconds (Finish - event declared).

Here's an example I've written an event handler using both using a delegate (UpdateTime) and an Event (Finished):

Public Class TimerState
    Public Delegate Sub UpdateTime(ByVal Countdown As Double)
    Public Event Finished(ByVal msg As String)

    Public Event update As UpdateTime

    Public Sub StartCountdown(ByVal Duration As Double, _
                              ByVal Increment As Double)
        Dim Start As Double = DateAndTime.Timer
        Dim ElapsedTime As Double = 0

        Dim SoFar As Double = 0
        Do While ElapsedTime < Duration
            If ElapsedTime > SoFar + Increment Then
                SoFar += Increment
                RaiseEvent update(SoFar)
            End If
            ElapsedTime = DateAndTime.Timer - Start
        Loop
        RaiseEvent Finished(ElapsedTime.ToString)
    End Sub

End Class

Then in the application I do this...

Public WithEvents mText As TimerState

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Button1.Text = "Start"
        mText = New TimerState
    End Sub

    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        mText.StartCountdown(5.0, 0.1)
    End Sub

    Private Sub mText_UpdateComplete(ByVal msg As String) Handles mText.Finished
        TextBox2.Text = "Done. Time Elapsed=" + msg
    End Sub


    Private Sub mText_UpdateTime(ByVal Countdown As Double) Handles mText.update
        TextBox1.Text += Countdown.ToString + ","
    End Sub

Your help in clearing up my confusion and differences would be grately appreciated....
 
Old June 3rd, 2008, 09:31 AM
planoie's Avatar
Friend of Wrox
 
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

Your query piqued my interest so I did a little investigation to satisfy my curiosity.

It appears there is basically no difference between the two declaration techniques. I created this simple class:
Code:
Class Events

   'Technique 1
   Public Delegate Sub UpdateTime(ByVal Countdown As Double)
   Public Event Event1 As UpdateTime

   'Technique 2
   Public Event Event2(ByVal Countdown As Double)

End Class
In technique 1 you are explicitly defining a delegate (which is compiled into a class derived from System.MulticastDelegate). In technique 2, the compiler is doing this for you. Take a look at the disassembled MSIL code for each:
Code:
  //Technique 1
  .class auto ansi sealed nested public UpdateTime
         extends [mscorlib]System.MulticastDelegate
    ...
  .event EventDefinitions.Events/UpdateTime Event1

  //Technique 2
  .class auto ansi sealed nested public Event2EventHandler
         extends [mscorlib]System.MulticastDelegate
    ...
  .event EventDefinitions.Events/Event2EventHandler Event2
Apart from names of objects, all the other code is identical.

The benefit of using a predefined delegate is that you can reuse that same delegate for multiple events. Otherwise, it seems there is no difference once the code is compiled.

-Peter
compiledthoughts.com
 
Old June 3rd, 2008, 01:18 PM
Authorized User
 
Join Date: Aug 2006
Posts: 41
Thanks: 1
Thanked 0 Times in 0 Posts
Default

Thanks for your response and explanation. Much appreciated.

I presume when you say you can reuse the same delegate for multiple events, it could be declared in a helper class and called when needed? I presume then, you can reuse my "Finished" Event, as you mention there is no difference in my two declarations. So:

Public Event Finished(ByVal msg As String) could also be reusable?

From reading articles online/in books, event handling/delegates are a simple process that is explained very badly...one simple, real world example would clear up alot of confusion for developers like me when having to write their own handlers for the first time.
 
Old June 3rd, 2008, 03:47 PM
planoie's Avatar
Friend of Wrox
 
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

Quote:
quote:Originally posted by elwappo
 I presume when you say you can reuse the same delegate for multiple events, it could be declared in a helper class and called when needed?

Yes, you certainly can put your delegates in a reusable location. When I define delegates for something specific I usually keep them with the related functionality. But general use delegates would go into a generic delegates file in the project somewhere.

One important semantic here though: At least within the context of this conversion, you don't "call" a delegate. In this case we are defining delegates for purpose of defining event signatures. So you define an even on a class that matches that delegate signature. The class defining the event will eventually raise it. What you are really going is calling the "Invoke" method of a class (your delegate) that is derived from System.MulticastDelegate.

Quote:
quote:I presume then, you can reuse my "Finished" Event, as you mention there is no difference in my two declarations.
The only reuse you can make of an event defined on a class is to raise that event more than once. The event is just a member of the class, no different than a property or method. You reuse the types that define them and, by extension, those members. So you can create many instances of a class that has methods and the event is part of it so it is available to use.

Quote:
quote:From reading articles online/in books, event handling/delegates are a simple process that is explained very badly...
The problem I have found is that delegates are a tricky beast because they are used in different ways. As I've mentioned, a delegate is really just a class based on a specific type. However, because of the nature of the event driven model of .NET dealing with events is such a core aspect so there are language constructs that obfuscate the use of the delegate classes.

When we are dealing with class events we create "events" instead of creating explicit instances of a delegate class. Then instead of explicitly calling 'myEvent.Invoke(...)' we can call RaiseEvent myEvent() [VB] or just myEvent() [C#]. The need to think about events as class instances is abstracted away by the languages.

You can also use delegate instances as method callbacks. In this case they are treated more like data. In this case the data is a pointer to a method. You call that method like you call any other method, but instead of the method name you use the variable name of the delegate instance.

-Peter
compiledthoughts.com
 
Old June 3rd, 2008, 05:04 PM
Authorized User
 
Join Date: Aug 2006
Posts: 41
Thanks: 1
Thanked 0 Times in 0 Posts
Default

Peter,
your post has certainly cleared up alot of the grey areas I had around the subject. So thank you.

I can certainly see how not getting semantics correct can lead to confusion of understanding the subject. I've come across developers who will loosely explain a subject without using the correct terminology which doesn't help. I now appreciate why you don't "call" a delegate, and that an event defined withhin a class is just a member of that class.

I'm now reading your blogs with great interest. Re-writing URL's (April 2008) is certainly an area I'm currently interested in.

I'm currently investigating the redevelopment of an ASP.NET health encyclopaedia (written by another developer who has left no documentation). It uses and needs friendly URLs. And from my investigation so far, .NET 2.0 doesn't support friendly URLs very well unless you intercept the initial HTTP request. I suppose it'll keep me away from delegates for a while...
Kind Regards
 
Old June 4th, 2008, 09:05 AM
planoie's Avatar
Friend of Wrox
 
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

(Repost, brain fart.)

Quote:
quote:Originally posted by elwappo
 And from my investigation so far, .NET 2.0 doesn't support friendly URLs very well unless you intercept the initial HTTP request. I suppose it'll keep me away from delegates for a while...


Delegates and URL re-writing aren't interrelated such that you need one for the other.

Have you considered a standard Wiki application for your health encyclopedia? I have been using MediaWiki (the Wiki behind Wikipedia) and I've found it incredibly easy and fast (two tenets of Wikis).

-Peter
compiledthoughts.com
 
Old June 5th, 2008, 03:07 AM
Authorized User
 
Join Date: Aug 2006
Posts: 41
Thanks: 1
Thanked 0 Times in 0 Posts
Default

Sorry, I was making a quip when I mentioned URL rewriting would keep me away from Delegates for a while!

I have to develop the Health Encyclopaedia as it needs to integrate within a current .NET website page. Plus the underlying data structure is more complex than a standard wiki would offer. Otherwise I would have considered a free wiki....

Quote:
quote:
Delegates and URL re-writing aren't interrelated such that you need one for the other.

Have you considered a standard Wiki application for your health encyclopedia? I have been using MediaWiki (the Wiki behind Wikipedia) and I've found it incredibly easy and fast (two tenets of Wikis).





Similar Threads
Thread Thread Starter Forum Replies Last Post
custom delegate for ToolStripMenuItem maricar C# 4 September 4th, 2008 03:07 AM
Output Query to txt file from SQL Query everest SQL Server 2005 4 November 22nd, 2007 01:49 AM
What Is Delegate jayakumar.cj ASP.NET 1.0 and 1.1 Basics 1 July 15th, 2006 06:09 AM
Syntax error in query. Incomplete query clause. dispickle ADO.NET 3 April 16th, 2004 01:04 PM
Business Delegate Pattern for Accessing Remote EJB mlumsden BOOK: Expert One-on-One J2EE Design and Development 1 September 25th, 2003 03:31 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.