What sort of class does BeginInvoke return? How can I use it to call EndInvoke?
<p>I'm working my way bottom up through ASP.net, and I was setting up an old school delegate pattern:</p>

<pre><code>    public delegate void ProcessRequestDelegate(HttpContext context);

    public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
    {
        ProcessRequestDelegate asyncDelegate = new ProcessRequestDelegate(ProcessRequest);
        return asyncDelegate.BeginInvoke(context, cb, extraData);
    }

    public void EndProcessRequest(IAsyncResult result)
    {
       //?? profit?
    }
</code></pre>

<p>But I realized, I don't know what to cast the <code>IAsyncResult result</code> to in the <code>EndProcessRequest</code> function. I tried:</p>

<pre><code>    public void EndProcessRequest(IAsyncResult result)
    {
        // Compiler error because this is dumb
        ((ProcessRequestDelegate)result).EndInvoke(result);
    }
</code></pre>

<p>but obviously you can't cast result to a delegate. So what is the proper way to end the invocation. And more generally, what sort of class does <code>Delegate.BeginInvoke</code> return?</p>

<p><strong>Update</strong></p>

<p>So I tried this out:</p>

<pre><code>    public static void Main()
    {
        IAsyncResult result = BeginStuff("something", null, null);
        IAsyncResult result2 = BeginStuff("something else", null, null);

        EndStuff(result);
        EndStuff(result2);

        Console.ReadLine();
    }

    static Action&lt;String&gt; act = delegate(String str)
    {
        Thread.Sleep(TimeSpan.FromSeconds(2));
        Console.WriteLine("This seems to work");
        Thread.Sleep(TimeSpan.FromSeconds(2));
    };

    static Action&lt;String&gt; act2 = delegate(String str) { };

    public static IAsyncResult BeginStuff(String data, AsyncCallback callback, Object state)
    {
        return Program.act.BeginInvoke(data, callback, state);
    }

    public static void EndStuff(IAsyncResult result)
    {
        // This works fine no matter how many times BeginInvoke is called
        Program.act.EndInvoke(result);

        // This however will fail, because the delegate that began the invocation 
        // is not the same as the one that ends it.
        Program.act2.EndInvoke(result);
    }
</code></pre>

<p>and it seems to work fine. As long as <code>BeginInvoke</code>/<code>EndInvoke</code> are called using the same delegate, the runtime handles the rest (I guess that's what the IAsyncResult is for). If you try to end using a different delegate though, it will give you a kind reminder not to do that.</p>

<p><br/>
<strong>Another Update</strong></p>

<p>I found a better-er way to do this:</p>

<pre><code>public void Operation()
{
    throw new FaultException&lt;FrieldyError&gt;(new FrieldyError("returned with this error"));
}

public IAsyncResult BeginOperation(AsyncCallback callback, object state)
{
    return ((Action)Operation).BeginInvoke(callback, state);
}

public void EndOperation(IAsyncResult result)
{
    ((Action)Operation).EndInvoke(result);
}
</code></pre>

<p>Since you just need to be using the same type of delegate, you can use one of the pre-existing ones and it works fine. No need to declare a local/private delegate of your own. </p>

<p>Useful!</p>
