私は 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);
}
同じタイプのデリゲートを使用する必要があるだけなので、既存のもののいずれかを使用でき、それは正常に機能します。独自のローカル/プライベート デリゲートを宣言する必要はありません。
使える!