BeginInvoke返回什么类?如何使用它来调用EndInvoke?

时间:2013-03-12 12:15:13

标签: c#

我正在通过ASP.net自下而上,我正在建立一个旧的学校代表模式:

    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?
    }

但我意识到,我不知道在IAsyncResult result函数中将EndProcessRequest转换为什么。我试过了:

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

但显然你无法将结果转换为委托。那么结束调用的正确方法是什么呢?更一般地说,Delegate.BeginInvoke返回什么类?

更新

所以我尝试了这个:

    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<String> act = delegate(String str)
    {
        Thread.Sleep(TimeSpan.FromSeconds(2));
        Console.WriteLine("This seems to work");
        Thread.Sleep(TimeSpan.FromSeconds(2));
    };

    static Action<String> 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);
    }

它似乎工作正常。只要使用相同的委托调用BeginInvoke / EndInvoke,运行时就会处理其余的(我猜这就是IAsyncResult的用途)。如果你试图结束使用不同的代表,它会给你一个提醒,不要那样做。


另一次更新

我找到了更好的方法:

public void Operation()
{
    throw new FaultException<FrieldyError>(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);
}

由于您只需要使用相同类型的委托,您可以使用其中一个预先存在的委托,它可以正常工作。无需声明自己的本地/私人代表。

有用!

3 个答案:

答案 0 :(得分:3)

Delegate.BeginInvoke返回的具体类是什么,无论它是什么,接口提供了等待其完成所需的所有内容(使用WaitHandle或轮询技术[无关紧要] examples])并致电EndInvoke

此外,您已经指定了AsyncCallback参数,不能将EndProcessRequest传递给它吗?

例如

this.BeginProcessRequest(
        HttpContext.Current, 
        this.EndProcessRequest, 
        "My extra data");

评论后修改:

如果您正在按照您的评论描述实施IHttpAsyncHandler,那么您应该遇到更少的问题,因为您可以将委托实例存储为您班级的成员

public class ProcessRequestAsyncHandler ; IHttpAsyncHandler 
{
   private  ProcessRequestDelegate asyncDelegate;

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

    public void EndProcessRequest(IAsyncResult result)
    {
        asyncDelegate.EndInvoke(result);
    }

    public bool IsReusable
    {
        get { return false; }
    }

    public void ProcessRequest(HttpContext context)
    {
       // Do something long-running
    }
}

参考:

答案 1 :(得分:2)

您可以将其转换为AsyncResult对象。这包含您的委托和AsyncState(您在extraData中传递的对象)等属性。要获得您的代表,您可以尝试这个

((ProcessRequestDelegate)((AsyncResult)result).AsyncDelegate)).EndInvoke();

AsyncDelegate属性获取调用异步调用的委托。

答案 2 :(得分:0)

哦,是的,似乎你必须这样做。这是你可以做的:

public void EndProcessRequest(IAsyncResult result)
{
    ProcessRequestDelegate del = (ProcessrequestDelegate) result.AsyncState;
    object item = del.EndInvoke(result)
}

本文中的here

相关问题