用标准的try/catch封装对类上方法的调用
本文关键字:方法 调用 catch 标准 try 封装 | 更新日期: 2023-09-27 18:18:46
我有一个类,它有大约200多个方法,这些方法中的每一个都对数据库或网络资源进行调用。
理想情况下,我希望将每个调用包装在try/catch中,以捕获任何常见的网络或SQL异常,并给用户再次尝试的机会(如果合适)。然而,将此代码添加到每个调用将非常耗时,并且就代码而言非常臃肿。
我考虑过在另一个方法中包装每个方法调用,创建一个委托,并在try/catch中包装委托代码。像这样…
(忽略语法…这只是一个概念性的例子)
bool CallUpdatePassenger(int PassengerId,string PassengerName,string PhoneNumber)
{
Delegate del= Delegate.CreateDelegate(typeof(UpdatePassengerDelegate), typeof(IPassengerServices).GetMethod("RemoteUpdatePassenger"));
bool Res=(bool)CallDelegate(del,PassengerName,PhoneNumber);
}
object CallDelegate(Delegate del,params object[] args)
{
object Result=null;
try
{
Result=del.DynamicInvoke(args);
}
catch (Some.Timeout.Error.Or.Whatever te)
{
// take some action.. maybe retry etc..
}
return Result;
}
也许有更实际的方法?
代码是自动生成的(由我编写的工具),我可以很容易地包含上面的东西,但我想避免为每个方法调用编写上面的代码。
同样,如果我像上面那样做,我可以计时方法,记录方法调用等。它只是看起来有点笨拙(而且不是强类型的)。
谢谢富有。
您应该能够像这样做:
T Execute<T>(Func<T> func) {
try {
return func();
} catch (...) {
...
}
}
bool CallUpdatePassenger(some args here) {
return Execute( () => realObj.RemoteUpdatePassenger(some args here));
}
或者,您可以使用元编程为底层方法动态编写一个"装饰器"…但除非你熟悉ILGenerator
等,否则最好不要这样做-这是一个相当高级的主题。
我认为你的基本想法很好,但是有一种更简单的方法来实现它(至少你们使用的是。net 3.5或更新的版本):
void WithStandardRetryLogic(Action method)
{
try
{
method();
}
catch (Some.Timeout.Error.Or.Whatever te)
{
// take some action.. maybe retry etc..
}
}
使用例子:
WithStandardRetryLogic(delegate() { CallUpdatePassenger(PassengerId, PassengerName, PhoneNumber); });
这可能也是AOP框架可能有用的地方,但我还没有尝试过那个解决方案。
如果你可以使用PostSharp,你可以使用这个方面:
[Serializable]
public class RetryAttribute : MethodInterceptionAspect
{
private readonly int _times;
public RetryAttribute(int times)
{
_times = times;
}
public override void OnInvoke(MethodInterceptionArgs args)
{
for (var left = _times; left > 0; left--)
{
try
{
args.Proceed();
break;
}
catch (Exception)
{
}
}
args.Proceed(); // optional
}
}
的用法如下:
[Retry(2)]
public static void DoIt()
{
Console.WriteLine("tried");
throw new Exception();
}
我认为其中一个可能的解决方案是AOP编程。您可以用属性标记任何方法,并在编译时注入try/catch
代码。
查看这里的示例