Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IAsyncResult

Tags:

c#

Why does IAsyncResult require I keep a reference to the Delegate that BeginInvoked it?

I would like to be able to write something like:

new GenericDelegate(DoSomething).BeginInvoke(DoSomethingComplete);

void DoSomethingComplete(IAsyncResult ar)
{
    ar.EndInvoke();
}
like image 958
James Avatar asked Mar 27 '09 04:03

James


People also ask

What is IAsyncResult?

The IAsyncResult interface is implemented by classes containing methods that can operate asynchronously. It is the return type of methods that initiate an asynchronous operation, such as FileStream. BeginRead, and it is passed to methods that conclude an asynchronous operation, such as FileStream.

What is AsyncCallback C#?

The AsyncCallback delegate represents a callback method that is called when the asynchronous operation completes. The callback method takes an IAsyncResult parameter, which is subsequently used to obtain the results of the asynchronous operation.


1 Answers

You don't need to keep your own reference to a delegate when doing a normal1 delegate BeginInvoke; you can cast the IAsyncResult to an AsyncResult and retrieve the delegate from the AsyncDelegate property. And before anybody says "that's a dirty hack", it's documented as being valid at MSDN.

The AsyncResult class is used in conjunction with asynchronous method calls made using delegates. The IAsyncResult returned from the delegate's BeginInvoke method can be cast to an AsyncResult. The AsyncResult has the AsyncDelegate property that holds the delegate object on which the asynchronous call was invoked.

So you could write:

new GenericDelegate(DoSomething).BeginInvoke(DoSomethingComplete);

void DoSomethingComplete(IAsyncResult ar)
{
    ((GenericDelegate)((AsyncResult)ar).AsyncDelegate)).EndInvoke();
}

Note that you do still have to know the type of the original delegate (or at least, I haven't found a way around this limitation; then again I haven't tried).


1 By "normal" here I mean a BeginInvoke on a delegate instance, using the compiler-generated method. This technique of casting to AsyncResult is not guaranteed to work when using pre-defined methods, i.e. when using a class which declares its own BeginX/EndX methods. This is because the class may be doing something more clever internally such as blocking on IO completion ports, and may therefore use a different type of IAsyncResult. However, in the scenario as posited, it will work just fine.

like image 70
Greg Beech Avatar answered Sep 22 '22 05:09

Greg Beech