国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

關于面向切面編程的部分內容-錯誤處理機制

2019-11-14 13:56:06
字體:
來源:轉載
供稿:網友

錯誤處理機制。

面對多個web服務器,多線程處理,我們想把錯誤信息記錄到一個txt文檔中。

但是把錯誤信息寫到內存是很快。寫到硬盤上就有一堆的問題。比如說讀寫慢、并發問題。

今天我們就利用這個實現錯誤處理 此文以MVC為例

1、首先要在  golable  文件的  PRotected void application_Start()


注冊一個錯誤處理機制。

MVC中自帶一個  過濾器

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

image

這里面 我們看到這個過濾器

 

2、其實就是在 app_Start文件夾下面 的 FilterConfig.cs 文件

image

3、 打開FilterConfig.cs文件

就寫了一個注冊事件。我們看得到 這個是對錯誤處理機制

image

(當然 ,你們看到的是  HandleErrorAttribute 這個類)

4、所以你們可能覺得奇怪,我們來查看MyExceptionAttribut的定義看一下

image

繼承了HandleErrorAttribute

這里我把這個類的代碼貼一下


public class MyExceptionAttribute : HandleErrorAttribute
    {
        //  private static object obj = new object();
        public static ConcurrentQueue<Exception> ExceptionQueue = new ConcurrentQueue<Exception>();//定義隊列

        /// <summary>
        /// 在該方法中捕獲異常。
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnException(ExceptionContext filterContext)
        {

            base.OnException(filterContext);
            Exception ex = filterContext.Exception;//捕獲異常信息。
            //將異常信息寫到隊列中。
            ExceptionQueue.Enqueue(ex);
            //跳轉到錯誤頁面.
            filterContext.HttpContext.Response.Redirect("/Error.html");

          

        }
    }

 

主要是定義一個靜態 隊列  ConcurrentQueue

(當然你也可以用 Queue。但是微軟說 這個ConcurrentQueue 比 Queue  安全。好像是線程安全的,一堆堆的理論,說白了就是用ConcurrentQueue 更安全)

這樣所有的錯誤就都在這個隊列里面了。(就是內存)

這樣總不行吧。內存 斷電就沒有了的啊。

所以我們要想把資料存到 硬盤中。

5、現在又要在

  golable  文件的  protected void Application_Start()


中注冊一個消費線程(這句話后面會解釋,看不懂就繼續)就是在 protected void Application_Start()中加入這些代碼,最好放最前面。

內容就是線程池開啟一個線程 從剛剛定義的 MyExceptionAttribute的 ExceptionQueue隊列里面取出項來。

將錯誤信息最加到文件后面。如果隊列為空,就線程停留3秒。


string filePath = Server.MapPath("/Log/");
            ThreadPool.QueueUserWorkItem((a) =>
            {

                while (true)//注意:線程不能結束。后面寫到隊列中的數據沒法處理。
                {

    // 這里可以加一條   if (MyExceptionAttribute.ExceptionQueue.Count() > 0)
//{  發送郵件到管理員}
                    if (MyExceptionAttribute.ExceptionQueue.Count() > 0)
                    {
                        // Exception ex= MyExceptionAttribute.ExceptionQueue.Dequeue();//從隊列中取出數據.
                        Exception ex = null;
                        bool isResult = MyExceptionAttribute.ExceptionQueue.TryDequeue(out ex);
                        if (ex != null && isResult)
                        {
                            string fullPath = filePath + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
                            File.AppendAllText(fullPath, ex.ToString());
                         //   ILog logger = LogManager.GetLogger("errorMsg");
                          //  logger.Error(ex.ToString());
                        }
                        else
                        {
                            Thread.Sleep(3000);
                        }
                    }
                    else
                    {
                        Thread.Sleep(3000);//避免造成CPU的空轉。
                    }
                }

 

            }, filePath);

6、總結。

這個就是一個生產者消費者的模式。

生產者就是 產生錯誤的源頭。 消費者就是注冊保存日志的方法。

中間有一個倉庫就是    那個靜態錯誤隊列。

可以看到 系統產生的錯誤臨時存放于內存中。然后一個新的線程 去讀寫靜態錯誤隊列。

正常情況 需要在錯誤隊列里面加一個錯誤隊列數字大于1000條的時候  發警告到郵箱的功能。那樣感覺有點問題復雜化了,畢竟這里只是講錯誤處理。

7、log4net 我前面講過的一個開源框架 記錄錯誤很好。

這里提供一個連接    log4net配置方法你可以把那個一起并到這里。那么就會有

把protected void Application_Start()中添加 的代碼

改成。注意是改成:

log4net.Config.xmlConfigurator.Configure();
            //開始一個線程,查看異常隊列
            string filePath = Server.MapPath("/Log/");
            ThreadPool.QueueUserWorkItem((a) =>
            {

                while (true)//注意:線程不能結束。后面寫到隊列中的數據沒法處理。
                {
                    if (MyExceptionAttribute.ExceptionQueue.Count() > 0)
                    {
                        // Exception ex= MyExceptionAttribute.ExceptionQueue.Dequeue();//從隊列中取出數據.
                        Exception ex = null;
                        bool isResult = MyExceptionAttribute.ExceptionQueue.TryDequeue(out ex);
                        if (ex != null && isResult)
                        {
                            string fullPath = filePath + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
                            //File.AppendAllText(fullPath, ex.ToString());
                            ILog logger = LogManager.GetLogger("errorMsg");
                            logger.Error(ex.ToString());
                        }
                        else
                        {
                            Thread.Sleep(3000);
                        }
                    }
                    else
                    {
                        Thread.Sleep(3000);//避免造成CPU的空轉。
                    }
                }

 

            }, filePath);

這樣就會按照你的要求把錯誤日志記錄到

app_data文件夾下面。(前提是你有未處理的錯誤 。呵呵)

看到下圖就成功了

image

題外話(

沒有就自己創一個   var s=3/0;

這樣就可以了。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 张家港市| 甘洛县| 奈曼旗| 五原县| 梁山县| 玛曲县| 武清区| 临邑县| 咸阳市| 绥德县| 延长县| 信宜市| 渝中区| 灵台县| 和顺县| 建水县| 溆浦县| 四平市| 明星| 十堰市| 二连浩特市| 孙吴县| 密云县| 安庆市| 九江市| 布拖县| 衡阳市| 桂平市| 芦山县| 嵊州市| 张掖市| 乡城县| 长沙县| 寻乌县| 甘谷县| 成安县| 宣城市| 慈利县| 南涧| 紫阳县| 新田县|