使用委托处理错误
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" 异常
我有一个常用方法来处理可能从多个函数返回的特定错误:
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
.