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/
<(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> 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" <(E-Mail Removed)> wrote in message
> news:#(E-Mail Removed)...
> > 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:%(E-Mail Removed)...
> > > 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(DataAvailabilityListener 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
> >
> >
>
>