使用委托进行错误处理

时间:2015-03-04 14:42:39

标签: c# error-handling task-parallel-library async-await task

我有一个常用的方法,我用它来处理可能从许多函数返回的特定错误:

protected async Task<T> RunMyMethod<T>(Func<T> method)
{
    try
    {
        var returnValue = await Task.Run<T>(method);
        return returnValue;
    }
    catch (MyCustomException)
    {
        // Force a clean shutdown of the software 
        ShutdownApplication();
        return default(T);
    }
}

以下是如何在派生类中使用它的示例:

private async Task<IEnumerable<MyData>> GetMyData()
{
    var returnValue = await base.RunMyMethod<IEnumerable<MyData>>(() =>
    {
        var returnval = GetMyDataFromServer();
        return returnval;
    });

    return returnValue;
}

MyCustomException中出现GetMyDataFromServer()类型的异常时,软件不会进入catch块。我在函数GetMyData()中收到以下错误:

An exception of type 'System.ServiceModel.FaultException`1' occurred in mscorlib.dll but was not handled in user code

Additional information: Exception of type 'MyCustomException' was thrown.

仅启用用户未处理的例外。

GetMyDataFromServer()与WCF服务进行通信。这项服务会引发错误。

ChannelFactory<TChannel> cf = new ChannelFactory<TChannel>(endPointName);
Binding binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);                    

var clientCredentials = new ClientCredentials();

. . .

channel = cf.CreateChannel();
var data = channel.CallWCFService();

环顾四周后,似乎正确处理此问题的方法是更改​​基本方法,如下所示:

protected async Task<T> RunMyMethod<T>(Func<T> method)
{
    var returnValue = await Task.Run<T>(method).ContinueWith(e => 
    {                     
        ShutdownApplication();
        return default(T);
    }, TaskContinuationOptions.OnlyOnFaulted);

    return returnValue;
}

当我运行它时,我显然没有捕获正确的错误消息,但我只是得到TaskCancellationException

所以,我有两个问题:关于如何处理这个异常的结论是正确的,如果是的话,我如何捕获一个特定的错误;为什么我得到TaskCancellationException

1 个答案:

答案 0 :(得分:1)

你得到TaskCancellationException,因为延续被取消,因为它是有条件的(即TaskContinuationOptions.OnlyOnFaulted),并且因为先前的任务没有出现故障,所以不满足条件。

没有理由使用这种添加延续的方法。像你在开始时那样使用async-await就足够了(甚至更简单)。

问题是你试图抓住MyCustomException,但这不是抛出的异常。由于您使用的是WCF,因此异常为FaultException。你可以检查&#34;真实&#34;存储在FaultException.InnerException中的异常。