.NET 异常处理的动作策略(Action Policy)

SQL Server 2008基于策略的管理,基于策略的管理(Policy Based Management),使DBA们可以制定管理策略,并将这些策略应用到服务器、数据库以及数据环境中的其他对象上去。基于动作策略(Action Policy)的异常处理使开发人员可以为异常处理制定策略,简单的说,动作策略只是一些可重复使用的一个装饰器,可以很容易应用与方法调用。

异常处理只是一个合乎逻辑的动作策略的一部分,动作策略决定如何对异常做出处理,微软的Enterprise Library的异常处理模块试图为开发人员和policy制定者为整个企业级应用程序各层的异常处理创建一致的策略。但是,异常处理的策略是硬编码的(也就是简单的try-catch代码块)。

如下是简单的示例代码:

try

{

customersDataSet = RunQuery(“GetAllCustomers”);

}

catch(Exception ex)

{

bool rethrow = ExceptionPolicy.HandleException(ex, “Data Access Policy”);

if (rethrow)

throw;

}

红色部分的Exception Policy是硬编码的,这里我给你介绍一种更好的基于动作策略(Action Policy)的异常处理,这个异常处理策略的的原理是充分利用C#的闭包Action,这个在园子里有很多讨论:

《你不常用的c#之三》:Action 之怪状

利用Reflector把"闭包"看清楚

Action其实就是一个委托

public delegate void Action();
public delegate void ActionPolicy(Action action);

很容易我们就可以实现一个出现异常情况下重试3次的策略

void MyRetryPolicy(Action action)
{
int counter = 0;
while (true)
{
try
{
      action();
return;
}
catch (DbException ex)
{
      counter+=1;
if (counter==3)
{
throw;
}
Thread.Sleep(1);
}
}
}

这个策略可以这样用

// 没有参数和返回值的简单调用
MyRetryPolicy(() => LongRunningDbCall());
MyRetryPolicy(() => AnotherFragileCall());
// 有一个参数和返回值的调用
int result = 0;
MyRetryPolicy(() => result = CreateRecords(records));

上述代码包含了两部分的逻辑,异常处理和行动策略。这个代码不够通用,可以包装一个行动策略。下面介绍一下在我的项目中使用的行动策略,我使用Autofac模块包装了行动策略,代码如下:

public class ActionPolicyModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.Register(c => ComposeActionPolicy(c));
            base.Load(builder);
        }

        static ActionPolicy ComposeActionPolicy(IComponentContext context)
        {
            ILog log = context.Resolve<ILog>();
            var actionPolicy = ActionPolicy.With(e => CompositeExceptionHandler(e, log))
               .Retry(3, (ex,i) =>
               {
                   log.DebugFormat(ex, "Retrying exception for the {0} time", i);
                   SystemUtil.Sleep((0.5 + i).Seconds());
               });

;
            return actionPolicy;
        }

        static bool CompositeExceptionHandler(Exception ex, ILog log)
        {
            ExceptionCounters.Default.Add(ex);

            if (ex.Message.Contains("Password"))
            {
                throw new SecuredException(ex);
            }

            if (ex is DbException)
            {
                return true;
            }

            log.Error(ex, "Unrecoverable exception");
            return false;
        }
    }

我们的方法中对策略的调用的代码很简单

public void AddAppliction(Application appInfo)
        {
            _scopes.Validate(appInfo, "AppInfo", AppRules.Appliction);
            _log.DebugFormat("AddAppliction()");
            _policy.Do( () => appRepository.AddAppliction(appInfo));
        }

_policy就是一个ActionPolicy对象,来自于Autofac内的策略配置,这样我们就可以在我们的代码中去除类似于微软的Enterprise Library的异常处理模块的硬编码代码。细心的你注意到了红色的代码中使用一个Retry Action Policy,出错的时候重试三次,每次之间间隔时间依次加长,重试了三次都不成功才抛出异常,这是一个很有用的功能,比如在数据库发生死锁的时候。动作策略还支持一种断路器,我们的生活中有一种很常见的电路断路器,在发生电涌或过载的时候保护我们的电路,我们的分布式系统中也会碰到类似的现象。

本文来自合作伙伴“doNET跨平台”,了解相关信息可以关注“opendotnet”微信公众号

时间: 2024-12-03 05:52:02

.NET 异常处理的动作策略(Action Policy)的相关文章

Spark转换(transform)与动作(action)一览

Spark转换(transform)与动作(action)一览. 以下func,大部分时候为了让逻辑更清楚,推荐使用匿名函数!(lambda)] [ps:java和python的api是一样的,名字和参数没有变化] 转换 含义 map(func) 每一个输入元素经过func函数转换后输出一个元素 filter(func) 返回经过 func 函数计算后返回值为 true 的输入元素组成的一个新数据集 flatMap(func) 类似于 map,但是每一个输入元素可以被映射为0或多个输出元素,因此

动作策略游戏《兵临城下》限免中

<兵临城下>是Triniti工作室的又一款休闲小作品,比较特殊的塔防游戏,说是塔防,但是它又有很多 即时战略的元素.比如,你可以用防守塔将基地团团围住,然后等待 敌人进攻.这款游戏中的敌人不会傻呆呆的去走你设计的路线,而是会主动攻击你的防御塔,你要不断的补塔,修塔,对抗敌人一波一波的进攻.<兵临城下>游戏截图<兵临城下>游戏截图游戏画面怀旧,颇有当年红警的风范,共有8种敌人(步兵坦克飞机等等俱全),四种防守塔,塔可升三级.唯一不足的是地图有点少,只有三副,不过看在它不到

DRL之:策略梯度方法 (Policy Gradient Methods)

DRL 教材 Chpater 11 --- 策略梯度方法(Policy Gradient Methods)   前面介绍了很多关于 state or state-action pairs 方面的知识,为了将其用于控制,我们学习 state-action pairs 的值,并且将这些值函数直接用于执行策略和选择动作.这种形式的方法称为:action-value methods. 下面要介绍的方法也是计算这些 action (or state) values,但是并非直接用于选择 action, 而

【IOS-COCOS2D游戏开发之十三】CCSPRITE利用BEZIER(贝塞尔)做抛物线动作并让CCSPRITE同时播放两个ACTION动作!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/iphone-cocos2d/480.html 如果我们想实现让CCSprite进行抛物线运动的话,那么我想童鞋们首先会想到利用Box2d或者其他物理引擎去为CCSprite创建物理世界中对应的刚体进行实现,但是反过来想,对于不熟悉Box2d或者其他物理引擎的童鞋,肯定不方便,那么Himi今天为大家介绍另外一种不实用物理引擎实现CCSprit

使用BizTalk Adatper for Web Service中的策略与技巧

web|策略|技巧 在使用BizTalk Adapter for Web Service的EAI解决方案中,不同的.分离的组件被整合在一起完成统一的商业逻辑.在解决方案中,各种组件必须很好的在一起工作.有两条关键的原则(key principle)可以使得你的BizTalk解决方案更完美: KP1:在搭建解决方案时,每一步实现均进行测试: KP2:丛最前端开始向后端推进,或丛最后端开始并向前端推进,一步一步进行增量开发.每进行一步增量开发,均要保证增量后解决方案可以使用. 下面分别加以描述,并对

jsonp突破同源策略,实现跨域访问请求

       跨域访问问题,相信大家都有遇到过.这是一个很棘手的问题.不过道高一尺,魔高一丈,对于这类问题,总有解决问题的方案.最近我又接触到了这个问题,解决的途径是ajax+jsonp.        说到这个问题,不得不说一下"同源策略(Same-Origin Policy)",它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源,就是必须协议.域名.端口都一致的,才叫做同源.例如:http://www.12306.c

在组策略的首选项和策略设置之间进行选择

从Windows Vista sp1和Windows Server 2008开始,组策略(Group Policy)和先前的版本有了更加长足的进步.细心的管理员可能已经发现,最新版本的组策略分成了策略设置(Policy Settings)和策略首选项(Policy Preferences)两个部分.其中策略设置基本上继承了以前版本组策略的主要内容,而策略首选项则是全新的内容,为管理员提供了更多更细的设置. 组策略设置和首选项的不同之处就在于强制性.组策略设置是受管理的.强制实施的.而组策略首选项

Struts1.x系列教程(21):使用MappingDispatchAction类调用不同的Action方法

与LookupDispatchAction.DispatchAction不同,MappingDispatchAction类并不通过请求参数来指定动作,而是将一个Struts动作对应于一个Action方法.下面的例子演示了如何使用MappingDispatchAction类来将Struts动作和Action方法相对应. Action类的实现代码: package action; import org.apache.struts.actions.MappingDispatchAction; -- p

如何使用组策略部署Windows防火墙

在管理规模较大的网络环境时,网络安全往往是花费精力最多的一环.就拿配置Windows XP SP2的防火墙来说,如果让网管为网内计算机逐一进行配置的话,工作量会非常大,而且在细节配置上也容易出错.那么,如何才能提高规模化环境内的防火墙配置效率呢? Windows防火墙是Windows XP SP2中一个极为重要的安全设计,它可以有效地协助我们完成计算机的安全管理.今天,笔者将为大家介绍如何使用组策略(Group Policy)在机房中集中部署Windows防火墙,提高为网内计算机配置防火墙的效率