The implementation of IAsyncResult is explicit

I generally fear partially implementing the interfaces. However, IAsyncResult is a special case, given that it supports several completely different usage patterns. How often do you use / see the AsyncState / AsyncCallback , not just an EndInvoke call using AsyncWaitHandle or IsCompleted (yuck) polling?

Related question: Finishing Workjtem ThreadPool completion / completion completion .

Consider this class (very rough, blocking required):

 public class Concurrent<T> { private ManualResetEvent _resetEvent; private T _result; public Concurrent(Func<T> f) { ThreadPool.QueueUserWorkItem(_ => { _result = f(); IsCompleted = true; if (_resetEvent != null) _resetEvent.Set(); }); } public WaitHandle WaitHandle { get { if (_resetEvent == null) _resetEvent = new ManualResetEvent(IsCompleted); return _resetEvent; } public bool IsCompleted {get; private set;} ... 

It has WaitHandle (lazily created as described in the IAsyncResult documentation) and IsCompleted , but I don't see a reasonable implementation for AsyncState ( {return null;} ?). Does it make sense to implement IAsyncResult ? Note that Task in the parallel extension library implements IAsyncResult , but only IsCompleted is implemented implicitly.

+6
c # asynchronous concurrency iasyncresult
source share
2 answers
  • In my experience, simply calling EndInvoke without waiting or going back is rarely useful.
  • Just providing callbacks is sometimes not enough, as your clients may want to wait for several operations at once (WaitAny, WaitAll)
  • I have never tried IsCompleted, yes! That way you can keep the implementation of IsCompleted, but it is so simple that it seems you should not potentially surprise your customers.

Thus, a reasonable implementation for an asynchronously called method should really provide a fully implemented IAsyncResult.

By the way, you often do not need to implement IAsyncResult yourself, just return what is returned by the .BeginInvoke delegate. See an example implementation of System.IO.Stream.BeginRead.

+2
source share

You seem to have a couple of questions. Let them be processed individually

Making WaitHandle Lazy

Yes, this is the most correct approach. You should do this streaming, but lazy is the way to go.

The trick, though, eliminates WaitHandle. WaitHandle is the IDisposable base and must be deleted in a timely manner. The documentation for IAsycResult does not apply to this case. The best way to do this is in EndInvoke. The documentation for BeginInvoke explicitly states that for each BeginInvoke there must be a corresponding EndInvoke (or BeginRead / EndRead). This is the best place to stay WaitHandle.

How to implement AsyncState?

If you look at the standard BCL API that IAsyncResult returns, most of them take a status parameter. This is usually the value returned from AsyncState (see Socket API Example). It is good practice to include a state variable typed as an object for any BeginInvoke API that returns IAsyncResult. Not necessarily, but good practice.

In the absence of a state variable, a null value is returned.

IsCompleted API

This will depend heavily on the implementation that creates the IAsyncResult. But yes, you must implement this.

+3
source share

All Articles