---记录错误日记 log------------ 队列Queue

1》定义一个错误日记类

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Utility
{
    public class LogHelper
    {
        //创建一个队列
        private static Queue<string> qu = new Queue<string>();

        /// <summary>
        /// 只要有错误,就将错误信息放入队列中
        /// </summary>
        /// <param name="ex"></param>
        public static void WriteLog(Exception ex)
        {

            //为什么要加这个锁?因为可能会有多个人同时错日记,调用这个线程造成并发。
            //加锁:用于解决了多线程同时写文件的并发问题
            lock ("lok")
            {

                StringBuilder sb = new StringBuilder();

                sb.AppendLine("----------------" + DateTime.Now.ToString() + "-----------------------");
                sb.AppendLine(ex.Message);

                //把sb这个字符串放入内存当中去。(其实就是将sb这个字符串添加到qu这个队列中去)
                qu.Enqueue(sb.ToString());
            }
           


        }

        /// <summary>
        /// 我们不想每调用一次该方法就开启一个线程,如果没调用一次该方法就开启一个新线程,那么经过多次调用该方法后,就会产生多个新的线程,那么假如遇到多个人同时操作该方法,将错误信息写入log.txt文件就会造成并发问题。 那么我们希望这个方法就只能调用一次,然后它里面的现场就一直开启(死循环)。所以我们就会想到将这个方法放在当前类的静态构造函数中去调用。因为静态构造函数只调用一次。 这样就保证了,当前方法只调用一次,然后就一直开启方法里面的后台线程。这样也保证了只产生一个新子线程。从而保证了在多个人同时调用该方法的时候,也只有一个线程去执行将错误信息写入log.txt文件的操作,从而不会引起并发的问题。(因为只有一个子线程,并发是指多个线程同时操作一个文件产生的问题)
        /// </summary>
        public static void WriteTxt()
        {
            Thread th = new Thread(() =>
            {
                while (true)
                {
                    if (qu.Count > 0)
                    {
                        //AppDomain类:表示应用程序域,它是一个应用程序在其中执行的独立环境。 此类不能被继承。
                        //AppDomain.CurrentDomain表示:获取当前 System.Threading.Thread 的当前应用程序域。
                        //BaseDirectory表示:获取基目录,它由程序集冲突解决程序用来探测程序集。
                        using (StreamWriter sw = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "App_Data/log.txt", true))
                        {
                            sw.Write(qu.Dequeue());
                        }
                    }
                }

            });
            th.IsBackground = true;
            th.Start();
        }

        /// <summary>
        /// 因为静态构造函数只执行一次。
        /// 静态构造函数的作用是用于静态数据成员完成值的初始化。静态类不能创建对象,所以它的作用仅仅是用于静态数据成员完成值的初始化。
        ///并且静态构造函数只被执行一次,什么时候被执行呢?就是这个类被第一次调用的时候被执行。
        /// </summary>
        static LogHelper()
        {
            WriteTxt();
        }
    }
}


2》调用错误日记类

在Global.asax中调用

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using Utility;

namespace WebApp
{
    public class Global : System.Web.HttpApplication
    {

        protected void Application_Start(object sender, EventArgs e)
        {

        }

        protected void Session_Start(object sender, EventArgs e)
        {

        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            //string ip = Request.UserHostAddress;
            //if (ip == "::1")
            //{
            //    Response.Redirect("HtmlPage2.html");
            //}
        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {

        }

        protected void Application_Error(object sender, EventArgs e)
        {
            错误信息  (注意:Environment.NewLine表示换行符)
            //string errorMsg = Context.Error.Message + Environment.NewLine + Context.Error.StackTrace + Environment.NewLine;

            将错误信息写入到日记
            //File.AppendAllText(Server.MapPath("~/log.txt"),errorMsg);



            //记录错误日记
            Exception ex = HttpContext.Current.Error;
            LogHelper.WriteLog(ex);

            //跳转到错误页
            Response.Redirect("~/ErrorPage.html");
        }

        protected void Session_End(object sender, EventArgs e)
        {

        }

        protected void Application_End(object sender, EventArgs e)
        {

        }
    }
}

Queue和ArrayList有什么不同啊?

Queue:先进先出,不能重新排序,不能索引访问

ArrayList:可以重新排序,可以索引访问

Queue(队列)类主要实现了一个FIFO(First In First Out,先进先出)的机制。元素在队列的尾部插入(入队操作),并从队列的头部移出(出队操作)。在Queue中主要使用Enqueue、Dequeue、Peek三个方法对队进行操作。Enqueue方法用于将对象添加到 Queue 的结尾处;Dequeue方法移除并返回位于 Queue 开始处的对象;Peek方法用于返回位于 Queue 开始处的对象但不将其移除。


ArrayList类主要用于对一个数组中的元素进行各种处理。在ArrayList中主要使用Add、Remove、RemoveAt、Insert四个方法对栈进行操作。Add方法用于将对象添加到 ArrayList 的结尾处;Remove方法用于从 ArrayList 中移除特定对象的第一个匹配项;RemoveAt方法用于移除 ArrayList 的指定索引处的元素;Insert方法用于将元素插入 ArrayList 的指定索引处。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值