当前位置: 首页 > 科技观察

部分内容关于面向切面编程-错误处理机制

时间:2023-03-19 10:15:47 科技观察

错误处理机制。面对多个web服务器和多线程处理,我们希望将错误信息记录在一个txt文件中。但是将错误消息写入内存的速度很快。写入硬盘时出现一堆问题。比如读写慢,并发问题。今天我们用它来实现错误处理本文以MVC为例1.首先在golable文件的protectedvoidApplication_Start()中注册一个错误处理机制。MVC自带一个过滤器FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);这里我们看到这个过滤器2,其实就是app_Start文件夹下的FilterConfig.cs文件3,打开FilterConfig.cs文件,写一个注册事件。我们可以看出这是一个错误处理机制(当然,你看到的是HandleErrorAttribute类)4.所以你可能会觉得奇怪,我们看一下MyExceptionAttribute的定义,看看是不是继承自HandleErrorAttribute。这里我贴一下这个类的代码。publicclassMyExceptionAttribute:HandleErrorAttribute{//privatestaticobjectobj=newobject();publicstaticConcurrentQueueExceptionQueue=newConcurrentQueue();//定义队列///

///在该方法中捕获异常。//////publicoverridevoidOnException(ExceptionContextfilterContext){base.OnException(filterContext);Exceptionex=filterContext.Exception;//捕获异常信息。//将异常信息写入队列。ExceptionQueue.Enqueue(ex);//跳转到错误页面.filterContext.HttpContext.Response.Redirect("/Error.html");}}主要定义了一个静态队列ConcurrentQueue(当然你也可以用Queue。但是微软据说这个ConcurrentQueue比Queue更安全,好像是线程安全的,理论也有很多,说白了还是用ConcurrentQueue更安全)这样所有的错误都在这个队列里。(是内存)这样不行。断电后记忆消失。所以我们要将数据保存到硬盘中。5、现在需要在golable文件的protectedvoidApplication_Start()中注册一个consumer线程(这句话后面会解释,不懂继续)就是在protectedvoidApplication_Start(),***放最后一个Front。内容是线程池启动一个线程从刚刚定义的MyExceptionAttribute的ExceptionQueue队列中取出项。将错误消息添加到文件末尾。如果队列为空,则线程停留3秒。stringfilePath=Server.MapPath("/Log/");ThreadPool.QueueUserWorkItem((a)=>{while(true)//注意:线程不能结束,后面写入队列的数据无法处理。{//这里可以加一个if(MyExceptionAttribute.ExceptionQueue.Count()>0)//{发送邮件给管理员}if(MyExceptionAttribute.ExceptionQueue.Count()>0){//Exceptionex=MyExceptionAttribute.ExceptionQueue。Dequeue();//从队列中取数据dd")+".txt";File.AppendAllText(fullPath,ex.ToString());//ILoglogger=LogManager.GetLogger("errorMsg");//logger.Error(ex.ToString());}else{Thread.Sleep(3000);}}else{Thread.Sleep(3000);//避免让CPU空转。}}},文件路径);6.总结。这是一个生产者-消费者模型。生产者是错误的来源。消费者是注册保存日志的方法。中间有个仓库就是静态错误队列。可以看出,系统产生的错误是暂时保存在内存中的。然后一个新线程读取和写入静态错误队列。一般情况下,需要在错误队列中添加错误队列数大于1000时,向邮箱发送警告的功能。那样感觉有点复杂,毕竟这只是错误处理。7.log4net前面提到的一个开源框架,可以很好的记录错误。这是一个链接log4net配置方法,您可以在此处将其合并在一起。那么在protectedvoidApplication_Start()中添加的代码就会发生变化。注意改为:log4net.Config.XmlConfigurator.Configure();//启动一个线程,检查异常队列stringfilePath=Server.MapPath("/Log/");ThreadPool.QueueUserWorkItem((a)=>{while(true)//注意:线程不能结束,写入队列的数据后面不能处理{if(MyExceptionAttribute.ExceptionQueue.Count()>0){//Exceptionex=MyExceptionAttribute.ExceptionQueue.Dequeue();//从队列中提取数据from.Exceptionex=null;boolisResult=MyExceptionAttribute.ExceptionQueue.TryDequeue(outex);if(ex!=null&&isResult){stringfullPath=filePath+DateTime.Now.ToString("yyyy-MM-dd")+".txt";//File.AppendAllText(fullPath,ex.ToString());ILoglogger=LogManager.GetLogger("errorMsg");logger.Error(ex.ToString());}else{Thread.Sleep(3000);}}else{Thread.Sleep(3000);//避免CPU空转}}},filePath);这样错误日志就会根据你的要求记录在app_data文件夹中。(前提是你有未处理的错误。呵呵)看到下图你就成功了。题外话(如果你不这样做,自己创建一个vars=3/0;就是这样。)