使用委托处理错误

Error handling using delegates

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

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);
    }
}

下面是一个如何在派生 class 中使用它的示例:

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?

您得到 TaskCancellationException,因为继续被取消是有条件的(即 TaskContinuationOptions.OnlyOnFaulted),并且由于前面的任务没有出错,所以不满足条件。

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

问题是您正在尝试捕获 MyCustomException 但这不是抛出的异常。由于您使用的是 WCF,因此例外情况是 FaultException。您可以检查存储在 FaultException.InnerException.

中的 "real" 异常