tags:

views:

162

answers:

1

I've got a class which is catching the System.Diagnostics.DataReceivedEventArgs event.

I want to make this event externally available. To accomplish that currently I'm catching this internally and raising another event, which seems like a bit duplication to me.

What's the best way to this? Can I wire these events so I do not need to raise a new event?

Here is the code :

Class MyClass  

Public Event OutputDataReceived(sender As Object, e As System.Diagnostics.DataReceivedEventArgs)

Public Sub Action()
    ....
     AddHandler Process.OutputDataReceived, AddressOf ReadData
    ....
End Sub

  Private Sub ReadData(ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs)
        RaiseEvent Me.OutputDataReceived(sender, e)
    End Sub

End Class
+8  A: 

What do you mean by "catching" the event? One thing you can do is expose your own event, which just passes on subscriptions/unsubscriptions to the other one:

public event DataReceivedEventHandler DataReceived
{
    add
    {
        realEventSource.DataReceived += value;
    }
    remove
    {
        realEventSource.DataReceived -= value;
    }
}

For more details on events, read my article on the topic - let me know if anything's unclear.

EDIT: Here's the equivalent in VB.NET:

Public Custom Event DataReceived As DataReceivedEventHandler
    AddHandler(ByVal value As DataReceivedEventHandler)
        AddHandler Me.realEventSource.DataReceived, value
    End AddHandler
    RemoveHandler(ByVal value As DataReceivedEventHandler)
        RemoveHandler Me.realEventSource.DataReceived, value
    End RemoveHandler
    RaiseEvent(ByVal sender as Object, ByVal args as DataReceivedEventArgs)
        Throw New NotSupportedException
    End RaiseEvent
End Event
Jon Skeet
Updated the question with the code I'm using right now, I hope that makes more sense now.
dr. evil
Your solution looks so elegant, however I think it's not possible to this in VB.NET, shame!
dr. evil
I'm pretty sure it *is* possible in VB.NET... will edit in a minute.
Jon Skeet
@Jon have you test your VB.NET code snippet? Apparently in VB.NET you need to use Custom Events which leads to at least 15 lines of code : http://www.codeguru.com/vb/gen/vb_general/idelanguage/article.php/c9481 and far more complicated than my initial (stupid yet working just fine) solution.
dr. evil
@Slough: I've fixed it so that it compiles. It doesn't need to be 15 lines, but I agree it's not as compact as in the C#. It's a shame that you have to include the RaiseEvent part.
Jon Skeet
`Throw New NotSupportedException` seems wrong to me. ;-) Why is it a shame that you need to include this? Au contraire: it makes the infamous C# `RaiseXYZ` method redundant. Why is it less compact than C#? The line count is exactly the same.
Konrad Rudolph
You know what Jon, you are a true "Rock Star", boy it works :) I'm waiting for your next book "VB.NET in Depth" :)
dr. evil
Thanks a lot, to be honest I was hopeless when I was asking the question, feel so good about this solution now.
dr. evil
@Konrad: Throwing NotSupportedException because generally (IMO) events should be about pub/sub: the outside world shouldn't be *raising* events, it should be *responding* to them. I rarely create "RaiseEvent" methods in C# - they break the encapsulation of events, IMO.
Jon Skeet
BTW does anyone know what's the original reason of RaiseEvent? Is it some sort of accesor in case you raise it from your own class?
dr. evil
@Konrad: Less compact than C# in terms of there being an extra concept. You could easily put "add { realEventSource.DataReceived += value; }" on one line and ditto for the remove. Look at the two versions in terms of "text on screen"...
Jon Skeet
@Slough: No chance of VB.NET in Depth. I touch VB when I have to, but I'm really not *familiar* with it :) As for the reason behind there being a RaiseEvent - not sure. As I've said, it goes against the pub/sub model IMO, and it should *at least* be optional for custom events. (cont)
Jon Skeet
It's not included in VB.NET "standard" events. It feels odd to *force* it to be included for custom events, but to *prevent* it from being included for standard ones. C# is more consistent in this, IMO - events *always* have exactly add/remove, whether custom or field-like. (cont.)
Jon Skeet
C# field-like events are far from perfect though - the synchronization model is broken. They try to be thread-safe, but very badly. Either you want real thread-safety, in which case you have to write a custom event, or you don't, in which case you don't want the locking overhead. Bah.
Jon Skeet