繁体   English   中英

BeginInvoke返回哪种类型的类? 如何使用它调用EndInvoke?

[英]What sort of class does BeginInvoke return? How can I use it to call EndInvoke?

我正在通过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);
}

由于您只需要使用相同类型的委托,因此您可以使用现有的委托之一,并且可以正常工作。 无需声明您自己的本地/私人代表。

有用!

对您而言无关紧要的是Delegate.BeginInvoke返回的具体类是什么,无论接口是什么,它都提供了您需要的所有内容,以等待其完成(使用WaitHandle或轮询技术[ 示例 ])并调用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
    }
}

参考:

您可以将其强制转换AsyncResult对象。 它包含诸如委托和AsyncState (您在extraData传递的对象)之类的extraData 要获得您的代表,可以尝试一下

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

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

哦,是的,看来您必须这样做。 您可以执行以下操作:

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

这篇文章在这里 o。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM