ASP.NET MVC自定义异常处理
1.自定义异常处理过滤器类文件
新建MyExceptionAttribute.cs异常处理类文件
MyExceptionAttribute.cs代码如下:
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace WebApp.Models{public class MyExceptionAttribute : HandleErrorAttribute{public static Queue<Exception> exceptionQueue = new Queue<Exception>(); //异常处理队列对象/// <summary>/// 控制器方法中出现异常,会调用该方法捕获异常/// </summary>/// <param name="filterContext"></param>public override void OnException(ExceptionContext filterContext){exceptionQueue.Enqueue(filterContext.Exception);//将捕获的异常信息写到队列中filterContext.HttpContext.Response.Redirect("/Error.html");//跳转到错误页面base.OnException(filterContext);}}}
2.将错误处理过滤器修改为自定义的异常处理过滤器
修改如下:
using System.Web;using System.Web.Mvc;using WebApp.Models;namespace WebApp{public class FilterConfig{public static void RegisterGlobalFilters(GlobalFilterCollection filters){//filters.Add(new HandleErrorAttribute());filters.Add(new MyExceptionAttribute());//使用自定义异常处理的过滤器}}}
3.修改Global.asax文件,在程序首次加载的时候,开启线程扫描异常队列,处理异常信息
using Spring.Web.Mvc;using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Threading;using System.Web;using System.Web.Http;using System.Web.Mvc;using System.Web.Optimization;using System.Web.Routing;using WebApp.Models;namespace WebApp{// 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,// 请访问 http://go.microsoft.com/?LinkId=9394801public class MvcApplication : SpringMvcApplication //System.Web.HttpApplication{protected void Application_Start(){AreaRegistration.RegisterAllAreas();WebApiConfig.Register(GlobalConfiguration.Configuration);FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);BundleConfig.RegisterBundles(BundleTable.Bundles);#region 开启线程扫描异队列,处理异常信息string fileLogPath = Server.MapPath("/Log/");//知道用来保存错误日志文件的文件夹路径//开启一个线程扫描日志队列ThreadPool.QueueUserWorkItem((a) =>{while (true){if (MyExceptionAttribute.exceptionQueue.Count > 0) //判断队列中是否有数据{Exception ex = MyExceptionAttribute.exceptionQueue.Dequeue();//出队if (ex != null){string fileName = DateTime.Now.ToString("yyyy-MM-dd") + ".txt";File.AppendAllText(fileLogPath + fileName, ex.ToString(), Encoding.Default);//将异常追加写入到文件中}else{Thread.Sleep(3000);}}else{Thread.Sleep(3000);//如果队列中没有数据,让当前线程休息3秒钟,避免造成CPU空转,避免CPU的浪费}}}, fileLogPath);#endregion}}}
4.测试:
public ActionResult Index(){int a = 2;int b = 0;int c = a / b;retu Content(c.ToString());}
5.效果
6.其他说明:
1.解决高并发错误日志问题:
1.1用传统lock方式,如果并发量很大的话,用户会出现卡顿的情况。
1.2.在服务器开辟一个队列,存储用户错误信息,然后单独开启一个线程来处理,就不会有卡顿情况。(队列是在内存中,写入速度很快)
这就是生产者消费者模式
2.Global下Application_Start()方法只在程序首次执行时调用
3.ThreadPool线程池线程性能很好,比我们自己创建线程的效率要高很多。
4.池用来解决对象频繁创建的问题,频繁创建消耗性能。
5.Queue本身不是线程安全的,做下面的处理后就可以保证是线程内安全的了,就不会出现并发问题。
Queue queue = Queue.Synchronized(myQueue);
7.源码下载:
作者:IT浪潮之巅
来源链接:https://www.cnblogs.com/zxx193/p/5063663.html
版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。
2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。