我正在通过 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);
}
由于您只需要使用相同类型的委托,因此您可以使用预先存在的委托之一,它工作正常。无需声明您自己的本地/私人代表。
有用!