-2

所以我有以下内容:

private delegate Foo1 GetFooAsync1(Foo1 foo1);
private delegate Foo2 GetFooAsync2(Foo2 foo2);
private delegate Foo3 GetFooAsync3(Foo3 foo3);
private delegate Foo4 GetFooAsync4(Foo4 foo4);

private FooAsync1 foo1;
private FooAsync2 foo2;
private FooAsync3 foo3;
private FooAsync4 foo4;

并且列表一直在继续,然后在一个方法中,我不想在每个 EndInvoke 上尝试捕获,因为有时它确实会引发异常,但它不应该停止系统,并继续使用其他 Foos ..如果每个人都有一个 try catch ,就会在方法中占用太多空间。

有没有一种通用的方法来调用结束调用?所以我可以返回预期的结果?

var result1 = foo1.EndInvoke(fooIAsyncResult);
4

1 回答 1

0

为了以通用方式实现这一点,您需要声明一个覆盖EndInvoke这样的扩展方法:

public static class DelegateExtensions
{
    public static TResult EndInvoke<TDelegate, TResult>(this TDelegate asyncCaller, IAsyncResult asyncResult) where TDelegate : System.Delegate
    {
        TResult result = default(TResult);

        try
        {
            result = asyncCaller.EndInvoke(asyncResult);
        }
        catch ( Exception ex)
        {
            LogExceptionMessageOrWhatever(ex.Message);
            throw;
        }

        return result;
    }
}

但是,该过程将产生编译器错误。为什么?该类System.Delegate是一个特殊的类,不能在通用约束中使用。

那么你不能摆脱约束,并使用反射来调用正确的过程吗?

我想你可以,但这违背了使用泛型的目的。更好的解决方案是使您的委托具有通用性,然后重写扩展方法以仅针对该委托。

public delegate TFooResult GetFooAsync<TFooResult>();

public static class GetFooAsyncExtensions
{
    public static TFooResult EndInvoke<TFooResult>(this GetFooAsync<TFooResult> asyncCaller, IAsyncResult asyncResult)
    {
        TFooResult result = default(TFooResult);

        try
        {
            result = asyncCaller.EndInvoke(asyncResult);
        }
        catch ( Exception ex )
        {
            LogExceptionMessageOrWhatever(ex.Message);
            throw;
        }

        return result;
    }
}

现在你会EndInvoke像往常一样打电话。该框架将自动使用您的版本。

private void Main()
{
    Foo1Result foo1 = null;

    var foo1Factory = new GetFooAsync<Foo1Result>(
        () =>
        {
            return new Foo1Result();
        });


    foo1Factory.BeginInvoke(
        callback: asyncResult =>
            {
                foo1 = foo1Factory.EndInvoke(asyncResult);
            },
            @object: null);
}
于 2014-02-17T10:31:40.630 回答