In order to achieve this in a generic way, you'd need to declare an extension method that overrides EndInvoke
like this:
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;
}
}
However, that procedure will generate a compiler error. Why? The System.Delegate
class is a special class that cannot be used in generic constraints.
So can't you just get rid of the constraint, and use reflection to invoke the right procedure?
I suppose you could, but that defeats the purpose of using generics. A better solution would be to make your delegate generic, then rewrite the extension method to target only that 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;
}
}
Now you'd call EndInvoke
like you normally would. The framework will automatically use your version.
private void Main()
{
Foo1Result foo1 = null;
var foo1Factory = new GetFooAsync<Foo1Result>(
() =>
{
return new Foo1Result();
});
foo1Factory.BeginInvoke(
callback: asyncResult =>
{
foo1 = foo1Factory.EndInvoke(asyncResult);
},
@object: null);
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…