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

How do I isolate event-generating code in a derived class?

P: n/a
Hey all,

A class of mine needs to tell the outside world when its buffer is not
empty. The problem is that C# seems to force you to put the
event-raising code in the base class. To illustrate, consider what I'll
do in Java:

public interface DataAvailabilityListener extends java.util.EventListener {
void dataArrived(DataAvailabilityEvent event);
}

then, in my base class, I can do this:

public abstract class SmartQueue {
addDataAvailabilityListener(DataAvailabilityListen er listener);
}

then in my implementation class, say a memory-backed smart queue, I can
do this:

public class MemorySmartQueue implements SmartQueue {
public void poolForData() {
// data available!
while(iter.hasNext()) {
DataAvailabilityListener lis =
(DataAvailabilityListener)iter.next();
lis.dataArrived(someEvent);
}
}
}

Simple and straighforward. However, consider a C# implementation: in the
interface, I may have something like this:

public abstract class SmartQueue {
public event DataAvailabilityEventHandler DataArrived;
}

Now, consider what I have to do in MemorySmartQueue:

public class MemorySmartQueue : SmartQueue {
public override void poolForData() {
// data available!
if(DataArrived == null) {
// BZZZZTTT!!! Can only do this in SmartQueue!
DataArrived(this, args);
}
}
}

I can't believe this. Either I'm missing a really obvious thing, or I
have to deal with this... this... awkward mechanism. Why the hell
doesn't it allow me to raise an event in the derived class? I don't want
to put any behaviour in my abstract class, I want to put just an interface!

Is there any way around this? (Plus I hope Whidbey will give us a Set
collection, dammit).

TIA!
Elder
Nov 15 '05 #1
Share this Question
Share on Google+
18 Replies


P: n/a
Oops, please replace "implements" with "extends" :)

Elder Hyde wrote:
Hey all,

A class of mine needs to tell the outside world when its buffer is not
empty. The problem is that C# seems to force you to put the
event-raising code in the base class. To illustrate, consider what I'll
do in Java:

public interface DataAvailabilityListener extends java.util.EventListener {
void dataArrived(DataAvailabilityEvent event);
}

then, in my base class, I can do this:

public abstract class SmartQueue {
addDataAvailabilityListener(DataAvailabilityListen er listener);
}

then in my implementation class, say a memory-backed smart queue, I can
do this:

public class MemorySmartQueue implements SmartQueue {
public void poolForData() {
// data available!
while(iter.hasNext()) {
DataAvailabilityListener lis =
(DataAvailabilityListener)iter.next();
lis.dataArrived(someEvent);
}
}
}

Simple and straighforward. However, consider a C# implementation: in the
interface, I may have something like this:

public abstract class SmartQueue {
public event DataAvailabilityEventHandler DataArrived;
}

Now, consider what I have to do in MemorySmartQueue:

public class MemorySmartQueue : SmartQueue {
public override void poolForData() {
// data available!
if(DataArrived == null) {
// BZZZZTTT!!! Can only do this in SmartQueue!
DataArrived(this, args);
}
}
}

I can't believe this. Either I'm missing a really obvious thing, or I
have to deal with this... this... awkward mechanism. Why the hell
doesn't it allow me to raise an event in the derived class? I don't want
to put any behaviour in my abstract class, I want to put just an interface!

Is there any way around this? (Plus I hope Whidbey will give us a Set
collection, dammit).

TIA!
Elder

Nov 15 '05 #2

P: n/a
Hi,

It is standard to implement a method to fire the event, this method is the
event name prefixed with 'On'. So in your case the base class would have a
OnDataArrived, which can be called from anywhere. This has the advantage of
not having to cluter your code checking if the event has any delegates
before firing and also gives the derived implementation an alternative and
better performing method of handling the event by overriding the On...
method.

public abstract class SmartQueue
{
public event DataAvailabilityEventHandler DataArrived;

// This is called to fire the event
public void OnDataArrived( YourEventArgs e )
{
if ( DataArrived != null )
DataArrived( this, e );
}
}

public class MemorySmartQueue : SmartQueue
{
public override void poolForData()
{
// data available!
OnDataArrived( args ); // Fire the event
}
}
Hope this helps
--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Elder Hyde" <no_way> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hey all,

A class of mine needs to tell the outside world when its buffer is not
empty. The problem is that C# seems to force you to put the
event-raising code in the base class. To illustrate, consider what I'll
do in Java:

public interface DataAvailabilityListener extends java.util.EventListener { void dataArrived(DataAvailabilityEvent event);
}

then, in my base class, I can do this:

public abstract class SmartQueue {
addDataAvailabilityListener(DataAvailabilityListen er listener);
}

then in my implementation class, say a memory-backed smart queue, I can
do this:

public class MemorySmartQueue implements SmartQueue {
public void poolForData() {
// data available!
while(iter.hasNext()) {
DataAvailabilityListener lis =
(DataAvailabilityListener)iter.next();
lis.dataArrived(someEvent);
}
}
}

Simple and straighforward. However, consider a C# implementation: in the
interface, I may have something like this:

public abstract class SmartQueue {
public event DataAvailabilityEventHandler DataArrived;
}

Now, consider what I have to do in MemorySmartQueue:

public class MemorySmartQueue : SmartQueue {
public override void poolForData() {
// data available!
if(DataArrived == null) {
// BZZZZTTT!!! Can only do this in SmartQueue!
DataArrived(this, args);
}
}
}

I can't believe this. Either I'm missing a really obvious thing, or I
have to deal with this... this... awkward mechanism. Why the hell
doesn't it allow me to raise an event in the derived class? I don't want
to put any behaviour in my abstract class, I want to put just an interface!
Is there any way around this? (Plus I hope Whidbey will give us a Set
collection, dammit).

TIA!
Elder

Nov 15 '05 #3

P: n/a
How can we perform an Async event in C#?

Events are Synchronous usually. Do we just call BeginInvoke, if so, how
would we do this?

"Chris Taylor" <ch*************@hotmail.com> wrote in message
news:#G**************@TK2MSFTNGP10.phx.gbl...
Hi,

It is standard to implement a method to fire the event, this method is the
event name prefixed with 'On'. So in your case the base class would have a
OnDataArrived, which can be called from anywhere. This has the advantage of not having to cluter your code checking if the event has any delegates
before firing and also gives the derived implementation an alternative and
better performing method of handling the event by overriding the On...
method.

public abstract class SmartQueue
{
public event DataAvailabilityEventHandler DataArrived;

// This is called to fire the event
public void OnDataArrived( YourEventArgs e )
{
if ( DataArrived != null )
DataArrived( this, e );
}
}

public class MemorySmartQueue : SmartQueue
{
public override void poolForData()
{
// data available!
OnDataArrived( args ); // Fire the event
}
}
Hope this helps
--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Elder Hyde" <no_way> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hey all,

A class of mine needs to tell the outside world when its buffer is not
empty. The problem is that C# seems to force you to put the
event-raising code in the base class. To illustrate, consider what I'll
do in Java:

public interface DataAvailabilityListener extends
java.util.EventListener {
void dataArrived(DataAvailabilityEvent event);
}

then, in my base class, I can do this:

public abstract class SmartQueue {
addDataAvailabilityListener(DataAvailabilityListen er listener);
}

then in my implementation class, say a memory-backed smart queue, I can
do this:

public class MemorySmartQueue implements SmartQueue {
public void poolForData() {
// data available!
while(iter.hasNext()) {
DataAvailabilityListener lis =
(DataAvailabilityListener)iter.next();
lis.dataArrived(someEvent);
}
}
}

Simple and straighforward. However, consider a C# implementation: in the
interface, I may have something like this:

public abstract class SmartQueue {
public event DataAvailabilityEventHandler DataArrived;
}

Now, consider what I have to do in MemorySmartQueue:

public class MemorySmartQueue : SmartQueue {
public override void poolForData() {
// data available!
if(DataArrived == null) {
// BZZZZTTT!!! Can only do this in SmartQueue!
DataArrived(this, args);
}
}
}

I can't believe this. Either I'm missing a really obvious thing, or I
have to deal with this... this... awkward mechanism. Why the hell
doesn't it allow me to raise an event in the derived class? I don't want
to put any behaviour in my abstract class, I want to put just an

interface!

Is there any way around this? (Plus I hope Whidbey will give us a Set
collection, dammit).

TIA!
Elder


Nov 15 '05 #4

P: n/a
Hi Chris,

So there's really no way of escaping this? The thing is that I want my
abstract class to be really just an interface, with no implementation.
The way I'd like to organize it is something like:

public abstract class SmartQueue {
// all interface stuff only, plus
// static methods
}

public abstract class AbstractSmartQueue : SmartQueue {
// put stuff that are common to base classes here.
}

public class MemorySmartQueue : AbstractSmartQueue {
// put memory-backed specific operations here
}

Now, I can't (or rather don't want to) make SmartQueue an interface,
because: I want to have static methods--it makes the most sense to put
them in SmartQueue. But anyway, OK, I know the way now. Thanks!

Regards,
Elder
Chris Taylor wrote:
Hi,

It is standard to implement a method to fire the event, this method is the
event name prefixed with 'On'. So in your case the base class would have a
OnDataArrived, which can be called from anywhere. This has the advantage of
not having to cluter your code checking if the event has any delegates
before firing and also gives the derived implementation an alternative and
better performing method of handling the event by overriding the On...
method.

public abstract class SmartQueue
{
public event DataAvailabilityEventHandler DataArrived;

// This is called to fire the event
public void OnDataArrived( YourEventArgs e )
{
if ( DataArrived != null )
DataArrived( this, e );
}
}

public class MemorySmartQueue : SmartQueue
{
public override void poolForData()
{
// data available!
OnDataArrived( args ); // Fire the event
}
}
Hope this helps

Nov 15 '05 #5

P: n/a
Hi,

Mistake in my code, in my haste, I forgot to make the On.... virtual SORRY.

public virtual void OnDataArrived( YourEventArgs e )

Regards

--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Chris Taylor" <ch*************@hotmail.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Hi,

It is standard to implement a method to fire the event, this method is the
event name prefixed with 'On'. So in your case the base class would have a
OnDataArrived, which can be called from anywhere. This has the advantage of not having to cluter your code checking if the event has any delegates
before firing and also gives the derived implementation an alternative and
better performing method of handling the event by overriding the On...
method.

public abstract class SmartQueue
{
public event DataAvailabilityEventHandler DataArrived;

// This is called to fire the event
public void OnDataArrived( YourEventArgs e )
{
if ( DataArrived != null )
DataArrived( this, e );
}
}

public class MemorySmartQueue : SmartQueue
{
public override void poolForData()
{
// data available!
OnDataArrived( args ); // Fire the event
}
}
Hope this helps
--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Elder Hyde" <no_way> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hey all,

A class of mine needs to tell the outside world when its buffer is not
empty. The problem is that C# seems to force you to put the
event-raising code in the base class. To illustrate, consider what I'll
do in Java:

public interface DataAvailabilityListener extends
java.util.EventListener {
void dataArrived(DataAvailabilityEvent event);
}

then, in my base class, I can do this:

public abstract class SmartQueue {
addDataAvailabilityListener(DataAvailabilityListen er listener);
}

then in my implementation class, say a memory-backed smart queue, I can
do this:

public class MemorySmartQueue implements SmartQueue {
public void poolForData() {
// data available!
while(iter.hasNext()) {
DataAvailabilityListener lis =
(DataAvailabilityListener)iter.next();
lis.dataArrived(someEvent);
}
}
}

Simple and straighforward. However, consider a C# implementation: in the
interface, I may have something like this:

public abstract class SmartQueue {
public event DataAvailabilityEventHandler DataArrived;
}

Now, consider what I have to do in MemorySmartQueue:

public class MemorySmartQueue : SmartQueue {
public override void poolForData() {
// data available!
if(DataArrived == null) {
// BZZZZTTT!!! Can only do this in SmartQueue!
DataArrived(this, args);
}
}
}

I can't believe this. Either I'm missing a really obvious thing, or I
have to deal with this... this... awkward mechanism. Why the hell
doesn't it allow me to raise an event in the derived class? I don't want
to put any behaviour in my abstract class, I want to put just an

interface!

Is there any way around this? (Plus I hope Whidbey will give us a Set
collection, dammit).

TIA!
Elder


Nov 15 '05 #6

P: n/a
Happened to me all the time.. I hadn't been typing "virtual" for about 7
years, since I left C++ behind ;)

Chris Taylor wrote:
Hi,

Mistake in my code, in my haste, I forgot to make the On.... virtual SORRY.

public virtual void OnDataArrived( YourEventArgs e )

Regards

Nov 15 '05 #7

P: n/a
Hi,

You could use BeginInvoke, and remember to always call EndInvoke. The events
will still be fired synchroneously, but in a separate thread. Something like
the following should do, this will be limited to only one handler however.

public virtual void OnDataArrived( EventArgs e )
{
if ( DataArrived != null )
DataArrived.BeginInvoke( this, e, new AsyncCallback(
DataArrivedCompleted ), null );
}

private void DataArrivedCompleted( IAsyncResult ar )
{
if ( DataArrived != null )
DataArrived.EndInvoke( ar );
}

You could also just use a separate thread to fire the event in, that way you
can have multiple handlers.

public virtual void OnDataArrived( EventArgs e )
{
if ( DataArrived != null )
System.Threading.ThreadPool.QueueUserWorkItem( new
System.Threading.WaitCallback( FireDataArrived ), e );
}

private void FireDataArrived( object e )
{
if ( DataArrived != null )
DataArrived( this, (EventArgs)e );
}

Then you can also fire each handler individually.

public virtual void OnDataArrived( EventArgs e )
{
if ( DataArrived != null )
foreach( DataAvailabilityEventHandler d in
DataArrived.GetInvocationList() )
{
d.BeginInvoke( this, e, new AsyncCallback(DataArrivedEventComplete),
d );
}
}

private void DataArrivedEventComplete( IAsyncResult ar )
{
DataAvailabilityEventHandler e =
(DataAvailabilityEventHandler)ar.AsyncState;
e.EndInvoke( ar );
}

Of course you would have to make sure the caller is aware of this
non-standard event calling and manage thread syncronization for shared data
etc. This code also lacks significant error handling, but should leave you
with a number of options.

Hope this helps

--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
<di********@discussion.microsoft.com> wrote in message
news:Oj**************@TK2MSFTNGP11.phx.gbl...
How can we perform an Async event in C#?

Events are Synchronous usually. Do we just call BeginInvoke, if so, how
would we do this?

"Chris Taylor" <ch*************@hotmail.com> wrote in message
news:#G**************@TK2MSFTNGP10.phx.gbl...
Hi,

It is standard to implement a method to fire the event, this method is the event name prefixed with 'On'. So in your case the base class would have a OnDataArrived, which can be called from anywhere. This has the advantage

of
not having to cluter your code checking if the event has any delegates
before firing and also gives the derived implementation an alternative and better performing method of handling the event by overriding the On...
method.

public abstract class SmartQueue
{
public event DataAvailabilityEventHandler DataArrived;

// This is called to fire the event
public void OnDataArrived( YourEventArgs e )
{
if ( DataArrived != null )
DataArrived( this, e );
}
}

public class MemorySmartQueue : SmartQueue
{
public override void poolForData()
{
// data available!
OnDataArrived( args ); // Fire the event
}
}
Hope this helps
--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Elder Hyde" <no_way> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hey all,

A class of mine needs to tell the outside world when its buffer is not
empty. The problem is that C# seems to force you to put the
event-raising code in the base class. To illustrate, consider what I'll do in Java:

public interface DataAvailabilityListener extends

java.util.EventListener
{
void dataArrived(DataAvailabilityEvent event);
}

then, in my base class, I can do this:

public abstract class SmartQueue {
addDataAvailabilityListener(DataAvailabilityListen er listener);
}

then in my implementation class, say a memory-backed smart queue, I can do this:

public class MemorySmartQueue implements SmartQueue {
public void poolForData() {
// data available!
while(iter.hasNext()) {
DataAvailabilityListener lis =
(DataAvailabilityListener)iter.next();
lis.dataArrived(someEvent);
}
}
}

Simple and straighforward. However, consider a C# implementation: in the interface, I may have something like this:

public abstract class SmartQueue {
public event DataAvailabilityEventHandler DataArrived;
}

Now, consider what I have to do in MemorySmartQueue:

public class MemorySmartQueue : SmartQueue {
public override void poolForData() {
// data available!
if(DataArrived == null) {
// BZZZZTTT!!! Can only do this in SmartQueue!
DataArrived(this, args);
}
}
}

I can't believe this. Either I'm missing a really obvious thing, or I
have to deal with this... this... awkward mechanism. Why the hell
doesn't it allow me to raise an event in the derived class? I don't want to put any behaviour in my abstract class, I want to put just an

interface!

Is there any way around this? (Plus I hope Whidbey will give us a Set
collection, dammit).

TIA!
Elder



Nov 15 '05 #8

P: n/a
I would assume this is a rare case that we would need async events then if
its so much hassle.
I am basically trying to draw a similarity between Win32 PostMessage and
SendMessage. Usually I used PostMessage as a way to fire events rather than
SendMessage wheras on C# I am using the equivilent to SendMessage now.

"Chris Taylor" <ch*************@hotmail.com> wrote in message
news:Oh**************@tk2msftngp13.phx.gbl...
Hi,

You could use BeginInvoke, and remember to always call EndInvoke. The events will still be fired synchroneously, but in a separate thread. Something like the following should do, this will be limited to only one handler however.

public virtual void OnDataArrived( EventArgs e )
{
if ( DataArrived != null )
DataArrived.BeginInvoke( this, e, new AsyncCallback(
DataArrivedCompleted ), null );
}

private void DataArrivedCompleted( IAsyncResult ar )
{
if ( DataArrived != null )
DataArrived.EndInvoke( ar );
}

You could also just use a separate thread to fire the event in, that way you can have multiple handlers.

public virtual void OnDataArrived( EventArgs e )
{
if ( DataArrived != null )
System.Threading.ThreadPool.QueueUserWorkItem( new
System.Threading.WaitCallback( FireDataArrived ), e );
}

private void FireDataArrived( object e )
{
if ( DataArrived != null )
DataArrived( this, (EventArgs)e );
}

Then you can also fire each handler individually.

public virtual void OnDataArrived( EventArgs e )
{
if ( DataArrived != null )
foreach( DataAvailabilityEventHandler d in
DataArrived.GetInvocationList() )
{
d.BeginInvoke( this, e, new AsyncCallback(DataArrivedEventComplete), d );
}
}

private void DataArrivedEventComplete( IAsyncResult ar )
{
DataAvailabilityEventHandler e =
(DataAvailabilityEventHandler)ar.AsyncState;
e.EndInvoke( ar );
}

Of course you would have to make sure the caller is aware of this
non-standard event calling and manage thread syncronization for shared data etc. This code also lacks significant error handling, but should leave you
with a number of options.

Hope this helps

--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
<di********@discussion.microsoft.com> wrote in message
news:Oj**************@TK2MSFTNGP11.phx.gbl...
How can we perform an Async event in C#?

Events are Synchronous usually. Do we just call BeginInvoke, if so, how
would we do this?

"Chris Taylor" <ch*************@hotmail.com> wrote in message
news:#G**************@TK2MSFTNGP10.phx.gbl...
Hi,

It is standard to implement a method to fire the event, this method is the event name prefixed with 'On'. So in your case the base class would have
a
OnDataArrived, which can be called from anywhere. This has the
advantage
of
not having to cluter your code checking if the event has any delegates
before firing and also gives the derived implementation an alternative

and better performing method of handling the event by overriding the On...
method.

public abstract class SmartQueue
{
public event DataAvailabilityEventHandler DataArrived;

// This is called to fire the event
public void OnDataArrived( YourEventArgs e )
{
if ( DataArrived != null )
DataArrived( this, e );
}
}

public class MemorySmartQueue : SmartQueue
{
public override void poolForData()
{
// data available!
OnDataArrived( args ); // Fire the event
}
}
Hope this helps
--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Elder Hyde" <no_way> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
> Hey all,
>
> A class of mine needs to tell the outside world when its buffer is
not > empty. The problem is that C# seems to force you to put the
> event-raising code in the base class. To illustrate, consider what

I'll > do in Java:
>
> public interface DataAvailabilityListener extends

java.util.EventListener
{
> void dataArrived(DataAvailabilityEvent event);
> }
>
> then, in my base class, I can do this:
>
> public abstract class SmartQueue {
> addDataAvailabilityListener(DataAvailabilityListen er listener);
> }
>
> then in my implementation class, say a memory-backed smart queue, I can > do this:
>
> public class MemorySmartQueue implements SmartQueue {
> public void poolForData() {
> // data available!
> while(iter.hasNext()) {
> DataAvailabilityListener lis =
> (DataAvailabilityListener)iter.next();
> lis.dataArrived(someEvent);
> }
> }
> }
>
> Simple and straighforward. However, consider a C# implementation: in the > interface, I may have something like this:
>
> public abstract class SmartQueue {
> public event DataAvailabilityEventHandler DataArrived;
> }
>
> Now, consider what I have to do in MemorySmartQueue:
>
> public class MemorySmartQueue : SmartQueue {
> public override void poolForData() {
> // data available!
> if(DataArrived == null) {
> // BZZZZTTT!!! Can only do this in SmartQueue!
> DataArrived(this, args);
> }
> }
> }
>
> I can't believe this. Either I'm missing a really obvious thing, or I > have to deal with this... this... awkward mechanism. Why the hell
> doesn't it allow me to raise an event in the derived class? I don't want > to put any behaviour in my abstract class, I want to put just an
interface!
>
> Is there any way around this? (Plus I hope Whidbey will give us a Set > collection, dammit).
>
> TIA!
> Elder



Nov 15 '05 #9

P: n/a

"Elder Hyde" <no_way> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hey all,

A class of mine needs to tell the outside world when its buffer is not
empty. The problem is that C# seems to force you to put the
event-raising code in the base class. To illustrate, consider what I'll
do in Java:

public interface DataAvailabilityListener extends java.util.EventListener { void dataArrived(DataAvailabilityEvent event);
}

then, in my base class, I can do this:

public abstract class SmartQueue {
addDataAvailabilityListener(DataAvailabilityListen er listener);
}

then in my implementation class, say a memory-backed smart queue, I can
do this:

public class MemorySmartQueue implements SmartQueue {
public void poolForData() {
// data available!
while(iter.hasNext()) {
DataAvailabilityListener lis =
(DataAvailabilityListener)iter.next();
lis.dataArrived(someEvent);
}
}
}

Simple and straighforward. However, consider a C# implementation: in the
interface, I may have something like this:

public abstract class SmartQueue {
public event DataAvailabilityEventHandler DataArrived;
}

Now, consider what I have to do in MemorySmartQueue:

public class MemorySmartQueue : SmartQueue {
public override void poolForData() {
// data available!
if(DataArrived == null) {
// BZZZZTTT!!! Can only do this in SmartQueue!
DataArrived(this, args);
}
}
}

I can't believe this. Either I'm missing a really obvious thing, or I
have to deal with this... this... awkward mechanism. Why the hell
doesn't it allow me to raise an event in the derived class? I don't want
to put any behaviour in my abstract class, I want to put just an interface!

It is an annoying thing. The CLR does allow for a protected raise_
method(atleast, by a vauge reading), however C# doesn't appear to support
this currently(MC++ is the only one I know that does.
Anyway, if you don't want any serious implementation in your base class, you
can do

public abstract class BaseClass
{
public event MyEventHandler MyEvent
{
add
{
Delegate.Combine(myEventDelegate,value);
}
remove
{
Delegate.Remove(myEventDelegate,value);
}
}
//this will contain the invocation list, might wanna convert this
//to a protected property so that you don't *have* to back off
myEventDelegate.
protected MyEventHandler myEventDelegate;
}
(note the syntax may be a touch off, I'm working from memory).
I would not be adverse to allowing a
raise
{

}
style method to events, however convincing the C# team of such may be
substatial work.
Is there any way around this? (Plus I hope Whidbey will give us a Set
collection, dammit).

TIA!
Elder

Nov 15 '05 #10

P: n/a
In addition to Chris's comments. I had a discussion about this in Oct 2003
on vb.dotnet.technical (recently converted to a web interface, I don't have
the new URL) titled "Multicast delegate guru's"

Our conclusion was you DONT! As BeginInvoke does not work on MultiCast
delegates, if you have more then a single handler attached to your event
(underlying delegate really), you cannot call BeginInvoke.

Here is the text from that thread:
---x--- cut here ---x---
By virtue of the error you are getting, the BeginInvoke method requires a
single method to use.

Which makes sense to me as when you are using BeginInvoke on your multicast
delegate are you expecting each routine to be on its own thread, or are you
expecting all routines to be on a single thread?

If you are expecting the first, I would not bother combining them I would
just BeginInvoke on each method (delegate). Alternatively you could use
Delegate.GetInvocationList and BeginInvoke on each method.

For the second I would have two delegates. The mutlicast delegate that has
the list of methods to execute, plus a singlecast delegate that is the
asynchronous method. This second routine would accept the multicast delegate
as a parameter, it would simply invoke the parameter.

Something like:

Delegate Sub Work(ByVal a As Integer, ByVal b As Integer)

Delegate Sub Worker(ByVal work As Work, ByVal a As Integer, ByVal b As
Integer)

Private Sub DoSub1(ByVal a As Integer, ByVal b As Integer)
' sub 1 process
End Sub

Private Sub DoSub2(ByVal a As Integer, ByVal b As Integer)
' sub 2 process
End Sub

' the asynchronous method
Private Sub DoWork(ByVal work As Work, ByVal a As Integer, ByVal b As
Integer)
work.Invoke(a, b)
End Sub

Dim sub1 As Work = AddressOf DoSub1
Dim sub2 As Work = AddressOf DoSub2
Dim work As Work = DirectCast([Delegate].Combine(sub1, sub2), Work)

Dim worker As Worker = AddressOf DoWork

worker.BeginInvoke(work, 1, 2, Nothing, Nothing)

---x--- cut here ---x---

Hope this helps
Jay


<di********@discussion.microsoft.com> wrote in message
news:Oj**************@TK2MSFTNGP11.phx.gbl...
How can we perform an Async event in C#?

Events are Synchronous usually. Do we just call BeginInvoke, if so, how
would we do this?

"Chris Taylor" <ch*************@hotmail.com> wrote in message
news:#G**************@TK2MSFTNGP10.phx.gbl...
Hi,

It is standard to implement a method to fire the event, this method is the event name prefixed with 'On'. So in your case the base class would have a OnDataArrived, which can be called from anywhere. This has the advantage

of
not having to cluter your code checking if the event has any delegates
before firing and also gives the derived implementation an alternative and better performing method of handling the event by overriding the On...
method.

public abstract class SmartQueue
{
public event DataAvailabilityEventHandler DataArrived;

// This is called to fire the event
public void OnDataArrived( YourEventArgs e )
{
if ( DataArrived != null )
DataArrived( this, e );
}
}

public class MemorySmartQueue : SmartQueue
{
public override void poolForData()
{
// data available!
OnDataArrived( args ); // Fire the event
}
}
Hope this helps
--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Elder Hyde" <no_way> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hey all,

A class of mine needs to tell the outside world when its buffer is not
empty. The problem is that C# seems to force you to put the
event-raising code in the base class. To illustrate, consider what I'll do in Java:

public interface DataAvailabilityListener extends

java.util.EventListener
{
void dataArrived(DataAvailabilityEvent event);
}

then, in my base class, I can do this:

public abstract class SmartQueue {
addDataAvailabilityListener(DataAvailabilityListen er listener);
}

then in my implementation class, say a memory-backed smart queue, I can do this:

public class MemorySmartQueue implements SmartQueue {
public void poolForData() {
// data available!
while(iter.hasNext()) {
DataAvailabilityListener lis =
(DataAvailabilityListener)iter.next();
lis.dataArrived(someEvent);
}
}
}

Simple and straighforward. However, consider a C# implementation: in the interface, I may have something like this:

public abstract class SmartQueue {
public event DataAvailabilityEventHandler DataArrived;
}

Now, consider what I have to do in MemorySmartQueue:

public class MemorySmartQueue : SmartQueue {
public override void poolForData() {
// data available!
if(DataArrived == null) {
// BZZZZTTT!!! Can only do this in SmartQueue!
DataArrived(this, args);
}
}
}

I can't believe this. Either I'm missing a really obvious thing, or I
have to deal with this... this... awkward mechanism. Why the hell
doesn't it allow me to raise an event in the derived class? I don't want to put any behaviour in my abstract class, I want to put just an

interface!

Is there any way around this? (Plus I hope Whidbey will give us a Set
collection, dammit).

TIA!
Elder



Nov 15 '05 #11

P: n/a
Elder,
The standard that Chris is referring to is documented in the following
topics:

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

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

Hope this helps
Jay

"Elder Hyde" <no_way> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hey all,

A class of mine needs to tell the outside world when its buffer is not
empty. The problem is that C# seems to force you to put the
event-raising code in the base class. To illustrate, consider what I'll
do in Java:

public interface DataAvailabilityListener extends java.util.EventListener { void dataArrived(DataAvailabilityEvent event);
}

then, in my base class, I can do this:

public abstract class SmartQueue {
addDataAvailabilityListener(DataAvailabilityListen er listener);
}

then in my implementation class, say a memory-backed smart queue, I can
do this:

public class MemorySmartQueue implements SmartQueue {
public void poolForData() {
// data available!
while(iter.hasNext()) {
DataAvailabilityListener lis =
(DataAvailabilityListener)iter.next();
lis.dataArrived(someEvent);
}
}
}

Simple and straighforward. However, consider a C# implementation: in the
interface, I may have something like this:

public abstract class SmartQueue {
public event DataAvailabilityEventHandler DataArrived;
}

Now, consider what I have to do in MemorySmartQueue:

public class MemorySmartQueue : SmartQueue {
public override void poolForData() {
// data available!
if(DataArrived == null) {
// BZZZZTTT!!! Can only do this in SmartQueue!
DataArrived(this, args);
}
}
}

I can't believe this. Either I'm missing a really obvious thing, or I
have to deal with this... this... awkward mechanism. Why the hell
doesn't it allow me to raise an event in the derived class? I don't want
to put any behaviour in my abstract class, I want to put just an interface!
Is there any way around this? (Plus I hope Whidbey will give us a Set
collection, dammit).

TIA!
Elder

Nov 15 '05 #12

P: n/a
Hi,

The following link more accurately defines what I was referring to in this
case.

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

Hope this helps

--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:OJ**************@tk2msftngp13.phx.gbl...
Elder,
The standard that Chris is referring to is documented in the following
topics:

http://msdn.microsoft.com/library/de...Guidelines.asp
http://msdn.microsoft.com/library/de...Guidelines.asp
Hope this helps
Jay

"Elder Hyde" <no_way> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hey all,

A class of mine needs to tell the outside world when its buffer is not
empty. The problem is that C# seems to force you to put the
event-raising code in the base class. To illustrate, consider what I'll
do in Java:

public interface DataAvailabilityListener extends
java.util.EventListener {
void dataArrived(DataAvailabilityEvent event);
}

then, in my base class, I can do this:

public abstract class SmartQueue {
addDataAvailabilityListener(DataAvailabilityListen er listener);
}

then in my implementation class, say a memory-backed smart queue, I can
do this:

public class MemorySmartQueue implements SmartQueue {
public void poolForData() {
// data available!
while(iter.hasNext()) {
DataAvailabilityListener lis =
(DataAvailabilityListener)iter.next();
lis.dataArrived(someEvent);
}
}
}

Simple and straighforward. However, consider a C# implementation: in the
interface, I may have something like this:

public abstract class SmartQueue {
public event DataAvailabilityEventHandler DataArrived;
}

Now, consider what I have to do in MemorySmartQueue:

public class MemorySmartQueue : SmartQueue {
public override void poolForData() {
// data available!
if(DataArrived == null) {
// BZZZZTTT!!! Can only do this in SmartQueue!
DataArrived(this, args);
}
}
}

I can't believe this. Either I'm missing a really obvious thing, or I
have to deal with this... this... awkward mechanism. Why the hell
doesn't it allow me to raise an event in the derived class? I don't want
to put any behaviour in my abstract class, I want to put just an

interface!

Is there any way around this? (Plus I hope Whidbey will give us a Set
collection, dammit).

TIA!
Elder


Nov 15 '05 #13

P: n/a
Chris,
Are you sure?

The link you gave is "Method Naming Guidelines".

Where as the two links I gave give Event Naming Guidelines & Event Usage
Guidelines.

Seeing as Elder was asking about Events I gave the two links on Events that
describe the "Standard" you mentioned in your first reply to him. How does
the Method Naming Guidelines come into play? Granted one of the two may be
more appropriate, however I find both together pretty much cover events.

Thanks
Jay

"Chris Taylor" <ch*************@hotmail.com> wrote in message
news:eb**************@TK2MSFTNGP12.phx.gbl...
Hi,

The following link more accurately defines what I was referring to in this
case.

http://msdn.microsoft.com/library/de...guidelines.asp
Hope this helps

--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:OJ**************@tk2msftngp13.phx.gbl...
Elder,
The standard that Chris is referring to is documented in the following
topics:

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

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

Hope this helps
Jay

"Elder Hyde" <no_way> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hey all,

A class of mine needs to tell the outside world when its buffer is not
empty. The problem is that C# seems to force you to put the
event-raising code in the base class. To illustrate, consider what I'll do in Java:

public interface DataAvailabilityListener extends

java.util.EventListener
{
void dataArrived(DataAvailabilityEvent event);
}

then, in my base class, I can do this:

public abstract class SmartQueue {
addDataAvailabilityListener(DataAvailabilityListen er listener);
}

then in my implementation class, say a memory-backed smart queue, I can do this:

public class MemorySmartQueue implements SmartQueue {
public void poolForData() {
// data available!
while(iter.hasNext()) {
DataAvailabilityListener lis =
(DataAvailabilityListener)iter.next();
lis.dataArrived(someEvent);
}
}
}

Simple and straighforward. However, consider a C# implementation: in the interface, I may have something like this:

public abstract class SmartQueue {
public event DataAvailabilityEventHandler DataArrived;
}

Now, consider what I have to do in MemorySmartQueue:

public class MemorySmartQueue : SmartQueue {
public override void poolForData() {
// data available!
if(DataArrived == null) {
// BZZZZTTT!!! Can only do this in SmartQueue!
DataArrived(this, args);
}
}
}

I can't believe this. Either I'm missing a really obvious thing, or I
have to deal with this... this... awkward mechanism. Why the hell
doesn't it allow me to raise an event in the derived class? I don't want to put any behaviour in my abstract class, I want to put just an

interface!

Is there any way around this? (Plus I hope Whidbey will give us a Set
collection, dammit).

TIA!
Elder



Nov 15 '05 #14

P: n/a
Sorry,

Actually the link I intended to supply was the second one you gave, I just
copied from the Address bar in explorer not noticing that the link did not
match the page, my mistake. I should have looked at your second link more
closely.

Again I apologize.

--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:eq*************@tk2msftngp13.phx.gbl...
Chris,
Are you sure?

The link you gave is "Method Naming Guidelines".

Where as the two links I gave give Event Naming Guidelines & Event Usage
Guidelines.

Seeing as Elder was asking about Events I gave the two links on Events that describe the "Standard" you mentioned in your first reply to him. How does
the Method Naming Guidelines come into play? Granted one of the two may be
more appropriate, however I find both together pretty much cover events.

Thanks
Jay

"Chris Taylor" <ch*************@hotmail.com> wrote in message
news:eb**************@TK2MSFTNGP12.phx.gbl...
Hi,

The following link more accurately defines what I was referring to in this
case.

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

Hope this helps

--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:OJ**************@tk2msftngp13.phx.gbl...
Elder,
The standard that Chris is referring to is documented in the following
topics:

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

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

Hope this helps
Jay

"Elder Hyde" <no_way> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
> Hey all,
>
> A class of mine needs to tell the outside world when its buffer is not > empty. The problem is that C# seems to force you to put the
> event-raising code in the base class. To illustrate, consider what I'll > do in Java:
>
> public interface DataAvailabilityListener extends

java.util.EventListener
{
> void dataArrived(DataAvailabilityEvent event);
> }
>
> then, in my base class, I can do this:
>
> public abstract class SmartQueue {
> addDataAvailabilityListener(DataAvailabilityListen er listener);
> }
>
> then in my implementation class, say a memory-backed smart queue, I can > do this:
>
> public class MemorySmartQueue implements SmartQueue {
> public void poolForData() {
> // data available!
> while(iter.hasNext()) {
> DataAvailabilityListener lis =
> (DataAvailabilityListener)iter.next();
> lis.dataArrived(someEvent);
> }
> }
> }
>
> Simple and straighforward. However, consider a C# implementation: in the > interface, I may have something like this:
>
> public abstract class SmartQueue {
> public event DataAvailabilityEventHandler DataArrived;
> }
>
> Now, consider what I have to do in MemorySmartQueue:
>
> public class MemorySmartQueue : SmartQueue {
> public override void poolForData() {
> // data available!
> if(DataArrived == null) {
> // BZZZZTTT!!! Can only do this in SmartQueue!
> DataArrived(this, args);
> }
> }
> }
>
> I can't believe this. Either I'm missing a really obvious thing, or I > have to deal with this... this... awkward mechanism. Why the hell
> doesn't it allow me to raise an event in the derived class? I don't want > to put any behaviour in my abstract class, I want to put just an
interface!
>
> Is there any way around this? (Plus I hope Whidbey will give us a Set > collection, dammit).
>
> TIA!
> Elder



Nov 15 '05 #15

P: n/a
Thanks guys!

Cheers
Elder
Nov 15 '05 #16

P: n/a
Chris,
copied from the Address bar in explorer not noticing that the link did not I hate when that happens!

I figured (was hoping) we were on the same "page" (so to say).

Thanks
Jay

"Chris Taylor" <ch*************@hotmail.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl... Sorry,

Actually the link I intended to supply was the second one you gave, I just
copied from the Address bar in explorer not noticing that the link did not
match the page, my mistake. I should have looked at your second link more
closely.

Again I apologize.

--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:eq*************@tk2msftngp13.phx.gbl...
Chris,
Are you sure?

The link you gave is "Method Naming Guidelines".

Where as the two links I gave give Event Naming Guidelines & Event Usage
Guidelines.

Seeing as Elder was asking about Events I gave the two links on Events that
describe the "Standard" you mentioned in your first reply to him. How does
the Method Naming Guidelines come into play? Granted one of the two may be more appropriate, however I find both together pretty much cover events.

Thanks
Jay

"Chris Taylor" <ch*************@hotmail.com> wrote in message
news:eb**************@TK2MSFTNGP12.phx.gbl...
Hi,

The following link more accurately defines what I was referring to in this case.

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

Hope this helps

--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:OJ**************@tk2msftngp13.phx.gbl...
> Elder,
> The standard that Chris is referring to is documented in the following > topics:
>
>

http://msdn.microsoft.com/library/de...Guidelines.asp
>
>

http://msdn.microsoft.com/library/de...Guidelines.asp
>
> Hope this helps
> Jay
>
> "Elder Hyde" <no_way> wrote in message
> news:%2****************@TK2MSFTNGP12.phx.gbl...
> > Hey all,
> >
> > A class of mine needs to tell the outside world when its buffer is not > > empty. The problem is that C# seems to force you to put the
> > event-raising code in the base class. To illustrate, consider what

I'll
> > do in Java:
> >
> > public interface DataAvailabilityListener extends
java.util.EventListener
> {
> > void dataArrived(DataAvailabilityEvent event);
> > }
> >
> > then, in my base class, I can do this:
> >
> > public abstract class SmartQueue {
> > addDataAvailabilityListener(DataAvailabilityListen er listener); > > }
> >
> > then in my implementation class, say a memory-backed smart queue,
I can
> > do this:
> >
> > public class MemorySmartQueue implements SmartQueue {
> > public void poolForData() {
> > // data available!
> > while(iter.hasNext()) {
> > DataAvailabilityListener lis =
> > (DataAvailabilityListener)iter.next();
> > lis.dataArrived(someEvent);
> > }
> > }
> > }
> >
> > Simple and straighforward. However, consider a C# implementation:
in the
> > interface, I may have something like this:
> >
> > public abstract class SmartQueue {
> > public event DataAvailabilityEventHandler DataArrived;
> > }
> >
> > Now, consider what I have to do in MemorySmartQueue:
> >
> > public class MemorySmartQueue : SmartQueue {
> > public override void poolForData() {
> > // data available!
> > if(DataArrived == null) {
> > // BZZZZTTT!!! Can only do this in SmartQueue!
> > DataArrived(this, args);
> > }
> > }
> > }
> >
> > I can't believe this. Either I'm missing a really obvious thing,
or I > > have to deal with this... this... awkward mechanism. Why the hell
> > doesn't it allow me to raise an event in the derived class? I
don't want
> > to put any behaviour in my abstract class, I want to put just an
> interface!
> >
> > Is there any way around this? (Plus I hope Whidbey will give us a

Set > > collection, dammit).
> >
> > TIA!
> > Elder
>
>



Nov 15 '05 #17

P: n/a
We were on the same page, I was just on the wrong planet! :)

--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:uB**************@TK2MSFTNGP12.phx.gbl...
Chris,
copied from the Address bar in explorer not noticing that the link did not
I hate when that happens!

I figured (was hoping) we were on the same "page" (so to say).

Thanks
Jay

"Chris Taylor" <ch*************@hotmail.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
Sorry,

Actually the link I intended to supply was the second one you gave, I just copied from the Address bar in explorer not noticing that the link did not match the page, my mistake. I should have looked at your second link more closely.

Again I apologize.

--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:eq*************@tk2msftngp13.phx.gbl...
Chris,
Are you sure?

The link you gave is "Method Naming Guidelines".

Where as the two links I gave give Event Naming Guidelines & Event Usage Guidelines.

Seeing as Elder was asking about Events I gave the two links on Events that
describe the "Standard" you mentioned in your first reply to him. How does the Method Naming Guidelines come into play? Granted one of the two may be
more appropriate, however I find both together pretty much cover
events.
Thanks
Jay

"Chris Taylor" <ch*************@hotmail.com> wrote in message
news:eb**************@TK2MSFTNGP12.phx.gbl...
> Hi,
>
> The following link more accurately defines what I was referring to in this
> case.
>
>

http://msdn.microsoft.com/library/de...guidelines.asp >
> Hope this helps
>
> --
> Chris Taylor
> http://dotnetjunkies.com/WebLog/chris.taylor/
> "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in

message
> news:OJ**************@tk2msftngp13.phx.gbl...
> > Elder,
> > The standard that Chris is referring to is documented in the following > > topics:
> >
> >
>

http://msdn.microsoft.com/library/de...Guidelines.asp
> >
> >
>

http://msdn.microsoft.com/library/de...Guidelines.asp
> >
> > Hope this helps
> > Jay
> >
> > "Elder Hyde" <no_way> wrote in message
> > news:%2****************@TK2MSFTNGP12.phx.gbl...
> > > Hey all,
> > >
> > > A class of mine needs to tell the outside world when its buffer is not
> > > empty. The problem is that C# seems to force you to put the
> > > event-raising code in the base class. To illustrate, consider
what I'll
> > > do in Java:
> > >
> > > public interface DataAvailabilityListener extends
> java.util.EventListener
> > {
> > > void dataArrived(DataAvailabilityEvent event);
> > > }
> > >
> > > then, in my base class, I can do this:
> > >
> > > public abstract class SmartQueue {
> > > addDataAvailabilityListener(DataAvailabilityListen er listener); > > > }
> > >
> > > then in my implementation class, say a memory-backed smart queue, I
can
> > > do this:
> > >
> > > public class MemorySmartQueue implements SmartQueue {
> > > public void poolForData() {
> > > // data available!
> > > while(iter.hasNext()) {
> > > DataAvailabilityListener lis =
> > > (DataAvailabilityListener)iter.next();
> > > lis.dataArrived(someEvent);
> > > }
> > > }
> > > }
> > >
> > > Simple and straighforward. However, consider a C#
implementation:
in the
> > > interface, I may have something like this:
> > >
> > > public abstract class SmartQueue {
> > > public event DataAvailabilityEventHandler DataArrived;
> > > }
> > >
> > > Now, consider what I have to do in MemorySmartQueue:
> > >
> > > public class MemorySmartQueue : SmartQueue {
> > > public override void poolForData() {
> > > // data available!
> > > if(DataArrived == null) {
> > > // BZZZZTTT!!! Can only do this in SmartQueue!
> > > DataArrived(this, args);
> > > }
> > > }
> > > }
> > >
> > > I can't believe this. Either I'm missing a really obvious thing, or
I
> > > have to deal with this... this... awkward mechanism. Why the

hell > > > doesn't it allow me to raise an event in the derived class? I

don't want
> > > to put any behaviour in my abstract class, I want to put just an
> > interface!
> > >
> > > Is there any way around this? (Plus I hope Whidbey will give us

a Set
> > > collection, dammit).
> > >
> > > TIA!
> > > Elder
> >
> >
>
>



Nov 15 '05 #18

P: n/a
It may be interesting to note the following from the VB.NET documentation:

"Derived classes - classes that inherit characteristics from a base class -
can handle events raised by their base class using the Handles MyBase
statement"

This seems directly contradicting what is otherwise given as the recommended
practice. The idea of a derived class setting itself up as a listener to
its base class seems like a kludge to me. I found this thread because I was
translating some VB code to C# and the author's use of Handles MyBase.event
didn't sit right with me.

I also found a third source in addition to the two Jay gave.
http://msdn.microsoft.com/library/de...guserinput.asp

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:OJ**************@tk2msftngp13.phx.gbl...
Elder,
The standard that Chris is referring to is documented in the following
topics:

http://msdn.microsoft.com/library/de...Guidelines.asp
http://msdn.microsoft.com/library/de...Guidelines.asp
Hope this helps
Jay

Nov 15 '05 #19

This discussion thread is closed

Replies have been disabled for this discussion.