0

I am looking to instantiating an AsyncResult object but there seems to be no AsyncResult class with a constructor in .Net Frameowork that I can instantiate.

Can someone provide a ready implementation of IAsynResult interface in C#? Or is there some trick way to instantiate an AsyncResult object?

Edit 1: I am creating an async task within an ASP.Net page. In the begin method, I call a data layer static method called 'AsyncBeginGetSummary'.

I would normally use ADO.Net BeginExecuteReader within this static method, which would work perfectly and I wouldn't need to instantiate an AsyncResult object. But, if the data object exists in Cache in ASP.Net app, then from this static method of ''AsyncBeginGetSummary', I do not want to call BeginExecuteReader.

But then, I still need to return AsyncResult object so the End method of the task in ASP.Net can be called. My ASP.Net page code is like below.

 IAsyncResult BeginAsyncOperation1(object sender, EventArgs e, AsyncCallback cb,
                                                           object state)
    {
         //call a static method from DAL that returns IAsyncResult.
         //call 'AsyncBeginGetSummary' static method in DAL
    }

    void EndAsyncOperation1(IAsyncResult ar)
    {
        //call a static method in DAL that gets your data here 
        //call 'AsyncEndGetSummary' static method in DAL
    }

Edit 2: I have the following where I do not need to bother about instantiating AsyncResult object since I use a dummy method delegate to call BeginInvoke.

 IAsyncResult BeginAsyncOperation1(object sender, EventArgs e, AsyncCallback cb, object state)
    {
         //call a static method from DAL that return IAsyncResult. 
         if((Cache["abc"] !=null)
         {
             return (new dummy(DummyMethod)).BeginInvoke(cb, new FinalDataForDocumentsSummary(listFromCache.Count, listFromCache));
         } 

        return NFM.Data.Mappers.DocumentsSummaryByProgramDataMapper.AsyncBeginEndDocumentsSummaryByProgramAll( vendorId, cb);

    }

    void EndAsyncOperation1(IAsyncResult ar)
    {
        //call a static method in DAL that gets your data here

    }



    public delegate void dummy();

    private void DummyMethod()
    {
    }

Edit 3: I have used the following AsyncResult implementation in WCF. I guess I could use it in ASP.Net also.

 class AsyncResult<T> : IAsyncResult
{
    private T data;
    private object state;
    private bool isCompleted = false;
    private AutoResetEvent waitHandle;
    private bool isSynchronous = false;

    public T Data
    {
        set { data = value; }
        get { return data; }
    }

    public AsyncResult(bool synchronous, object stateData)
    {
        isSynchronous = synchronous;
        state = stateData;
    }

    public void Complete()
    {
        isCompleted = true;
        ((AutoResetEvent)AsyncWaitHandle).Set();
    }

    public object AsyncState
    {
        get { return state; }
    }

    public WaitHandle AsyncWaitHandle
    {
        get
        {
            if (waitHandle == null)
                waitHandle = new AutoResetEvent(false);

            return waitHandle;
        }
    }

    public bool CompletedSynchronously
    {
        get
        {
            if (!isCompleted)
                return false;
            else
                return isSynchronous;
        }
    }

    public bool IsCompleted
    {
        get { return isCompleted; }
    }
}
Sunil
  • 20,653
  • 28
  • 112
  • 197
  • 2
    You should almost never need to create your own `IAsyncResult`. What are you trying to do? – SLaks Dec 30 '12 at 02:09
  • 2
    See http://msdn.microsoft.com/en-us/magazine/cc163467.aspx and http://blogs.msdn.com/b/nikos/archive/2011/03/14/how-to-implement-iasyncresult-in-another-way.aspx, but you probably should not be doing this. – SLaks Dec 30 '12 at 02:10
  • Please see Edit 1 under my post for what I am after. I think I could return a null for AsyncResult if the data is in cache rather tha instantiate AsyncResult object. – Sunil Dec 30 '12 at 02:23
  • 1
    I've gone down this path, and found it rather painful. You probably should re-think your approach, as there are easier ways to do this. In my particular situation, a Task made quick work of it. But even an asynchronous delegate would probably do what you want. – Jim Mischel Dec 30 '12 at 02:43
  • @JimMischel is right. Using the `Task` class will make this _much_ simpler. (`return Task.FromResult(...)`) – SLaks Dec 30 '12 at 03:21

1 Answers1

3

It sounds like you want an IAsyncResult that indicates synchronous completion – that the result is already available.

In that case, you can create your own simple class that returns true for IsCompleted and CompletedSynchronously, and returns the caller's parameter in AsyncState, and null for WaitHandle.

If you want the caller to be able to use the WaitHandle, you'll need to create a ManualResetEvent and dispose it at some point; see this article.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • SLaks - Thanks. Do you have a sample implementation? – Sunil Dec 30 '12 at 02:46
  • The implementations I linked to are much more complicated, since they deal with non-completed operations. – SLaks Dec 30 '12 at 02:46
  • How about just calling BeginInvoke on dummy method I create. This method could be called 'DummyMethod()' This will get the asyncresult object. Right? the callback will the callback I would pass to BeginExecuteReader. This seems ok to me. – Sunil Dec 30 '12 at 02:49
  • SLaks- Thanks. Which of my Edit 2 or Edit 3 solutions appears better in my situation according to you? – Sunil Dec 30 '12 at 03:14
  • @Sunil: Edit 2 is less efficient; Edit 3 leaks WaitHandles (which is bad). If you want to create WaitHandles, see my linked articles. – SLaks Dec 30 '12 at 03:32