• 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=9394801
    
        public 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;
                return 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.源码下载:

    点击下载源码>>

    点击下载数据库文件>>

  • 相关阅读:
    Linux tcpdump命令详解
    移动开发网站收集
    Struts+2权威指南基于WebWork核心的MVC开发源码下载
    Eclipse+php插件+Xdebug搭建PHP完美开发/调试环境指南
    java相对目录和绝对目录解析
    python学习网站搜集
    window下开发iphone程序环境搭建iphone tool chain
    Windows下编译objectiveC
    java class路径获取
    完全优化MySQL数据库性能的八个方法
  • 原文地址:https://www.cnblogs.com/zxx193/p/5063663.html
Copyright © 2020-2023  润新知