Ric*_*h S 19 .net c# delegates exception
我有一个有大约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;
}
Run Code Online (Sandbox Code Playgroud)
也许还有更实用的方法吗?
代码是自动生成的(通过我编写的工具)我可以很容易地包含上面的内容,但我想避免为每个方法调用编写上面的代码.
此外,如果我执行上述操作,我可以计时方法,并记录方法调用等.它看起来有点笨拙(而不是强类型).
谢谢Rich.
Mar*_*ell 32
你应该能够做以下事情:
T Execute<T>(Func<T> func) {
try {
return func();
} catch (...) {
...
}
}
bool CallUpdatePassenger(some args here) {
return Execute( () => realObj.RemoteUpdatePassenger(some args here));
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用元编程为动态基础方法编写动态"装饰器"...但除非您熟悉ILGenerator等等,否则最好不要 - 这是一个相当高级的主题.
cka*_*ras 12
我认为你的基本想法很好,但有一种更简单的方法来实现它(至少你使用的是.Net 3.5或更新版本):
void WithStandardRetryLogic(Action method)
{
try
{
method();
}
catch (Some.Timeout.Error.Or.Whatever te)
{
// take some action.. maybe retry etc..
}
}
Run Code Online (Sandbox Code Playgroud)
使用示例:
WithStandardRetryLogic(delegate() { CallUpdatePassenger(PassengerId, PassengerName, PhoneNumber); });
Run Code Online (Sandbox Code Playgroud)
这也可能是AOP框架可能有用的东西,但我还没有尝试过这个解决方案.