<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      星期一

      情景

      早晨,項(xiàng)目組長(zhǎng)來到小明身邊,“有人反映咱們的項(xiàng)目有Bug” “什么Bug?” “不知道,你添加一個(gè)日志模塊自己看記錄去?!?”...“

      分析

      在MVC全局過濾器中自己添加有異常過濾器。

      Global.asax
      1 public class MvcApplication : System.Web.HttpApplication 2 { 3 protected
      void Application_Start() 4 { 5 AreaRegistration.RegisterAllAreas(); 6 //
      注冊(cè)全局過濾器 7 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 8
      RouteConfig.RegisterRoutes(RouteTable.Routes); 9
      BundleConfig.RegisterBundles(BundleTable.Bundles);10 } 11 } View Code
      ?

      ?FilterConfig.cs
      1 public class FilterConfig 2 { 3 public static void
      RegisterGlobalFilters(GlobalFilterCollection filters)4 { 5 //向全局過濾器中添加異常過濾器 6
      //只要你的項(xiàng)目出現(xiàn)了異常,就會(huì)執(zhí)行過濾器里的OnException方法 7 filters.Add(new HandleErrorAttribute());
      8 } 9 } View Code
      ?

      開工

      整理思路:發(fā)生錯(cuò)誤時(shí)要執(zhí)行自己需要的代碼,只需要繼承IExceptionFilter,重寫OnException方法,然后把自己的過濾器注冊(cè)到全局即可。

      創(chuàng)建過濾器,MyExceptionFilter類
      1 //因?yàn)槲④浺呀?jīng)提供了一個(gè)HandleErrorAttribute類(它其實(shí)也是繼承了IExceptionFilter),所以我們只需繼承它即可 2
      public class MyExceptionFilter: HandleErrorAttribute 3 { 4 //重寫OnException方法
      5 public override void OnException(ExceptionContext filterContext) 6 { 7
      base.OnException(filterContext); 8 9 //把錯(cuò)誤寫到日志文件里面去 10 //
      思考:如果同時(shí)來了多個(gè)錯(cuò)誤,一起向文件中寫內(nèi)容,就會(huì)發(fā)生同時(shí)訪問同一個(gè)文件問題。你會(huì)怎么解決?11 //提示:鎖、隊(duì)列 12 13 //
      LogHelper類用來把錯(cuò)誤寫到日志里面去 14 LogHelper.Write(filterContext.Exception.ToString());
      15 16 } 17 }
      ?

      ?

      LogHelper類,用來把錯(cuò)誤寫到日志里面去
      1 public class LogHelper 2 { 3 //添加一個(gè)靜態(tài)的異常信息隊(duì)列,只要出現(xiàn)異常就寫到隊(duì)列中。 4 public
      static Queue<string> ExceptionStringQueue = new Queue<string>(); 5 6 //
      第一次用到該類型時(shí)會(huì)執(zhí)行靜態(tài)構(gòu)造函數(shù),只被執(zhí)行一次 7 static LogHelper() 8 { 9 //創(chuàng)建一個(gè)線程池,將方法排入隊(duì)列以便執(zhí)行
      10 ThreadPool.QueueUserWorkItem(o => { 11 while (true) 12 { 13 lock
      (ExceptionStringQueue)14 { 15 //如果有錯(cuò)誤信息寫入日志 16 if (ExceptionStringQueue.Count >
      0) 17 { 18 string exceptionString = ExceptionStringQueue.Dequeue(); 19 //
      把錯(cuò)誤信息寫到日志文件中 20 using (System.IO.StreamWriter file = new System.IO.StreamWriter(
      @"C:\Log.txt", true)) 21 { 22 file.WriteLine(exceptionString);// 直接追加文件末尾,換行 23
      }24 } 25 else 26 { 27 Thread.Sleep(1000); 28 } 29 30 } 31 } 32 }); 33 }
      34 35 36 //給外部提供方法,將錯(cuò)誤信息寫入隊(duì)列 37 public static void Write(string exceptionString)
      38 { 39 lock (ExceptionStringQueue) 40 { 41 //將錯(cuò)誤信息添加到隊(duì)列 42
      ExceptionStringQueue.Enqueue(exceptionString);43 } 44 } 45 } View Code
      ?

      把自己的過濾器注冊(cè)到全局
      1 public class FilterConfig 2 { 3 public static void
      RegisterGlobalFilters(GlobalFilterCollection filters) 4 { 5 //向全局過濾器中添加異常過濾器
      6 //只要你的項(xiàng)目出現(xiàn)了異常,就會(huì)執(zhí)行過濾器里的OnException方法 7 //filters.Add(new
      HandleErrorAttribute()); 8 //把自己的過濾器注冊(cè)到全局 9 filters.Add(new
      MyExceptionFilter());10 } 11 } View Code
      ?

      自定義錯(cuò)誤測(cè)試
      1 throw new Exception("自定義錯(cuò)誤"); View Code
      ?



      ?OK,大功告成,以后就可以根據(jù)日志來找錯(cuò)誤了。?

      星期二

      情景

      早晨,項(xiàng)目組長(zhǎng)又來到小明身邊,”昨天我用了你的錯(cuò)誤日志功能,還不錯(cuò),但是你將日志寫在文件中整理不是太方便,還存在共享沖突問題,你改下寫到數(shù)據(jù)庫(kù)中“ ”...“

      分析

      查看昨天寫的代碼



      發(fā)現(xiàn)此處是一個(gè)變化點(diǎn),有可能寫到文件中,有可能寫到數(shù)據(jù)庫(kù)中,有可能......

      不就是寫到不同的地方么,簡(jiǎn)單,多態(tài)就能搞定了。

      開工

      依賴于抽象,而不依賴于具體

      創(chuàng)建IWriteLog接口
      1 public interface IWriteLog 2 { 3 //把錯(cuò)誤信息寫到相應(yīng)的地方 4 void WriteLog(string
      exceptionString);5 } View Code
      創(chuàng)建WriteLogToText類實(shí)現(xiàn)接口,用來寫入文本
      1 public class WriteLogToText : IWriteLog 2 { 3 public void WriteLog(string
      exceptionString)4 { 5 //將錯(cuò)誤信息寫入文本 6 } 7 } View Code
      ?創(chuàng)建WriteLogToSqlServer類實(shí)現(xiàn)接口,用來寫入數(shù)據(jù)庫(kù)
      1 public class WriteLogToSqlServer : IWriteLog 2 { 3 public void WriteLog(
      string exceptionString) 4 { 5 //將錯(cuò)誤信息寫入數(shù)據(jù)庫(kù) 6 } 7 } View Code
      ?

      對(duì)變化點(diǎn)進(jìn)行修改
      1 string exceptionString = ExceptionStringQueue.Dequeue(); 2 //依賴接口 3
      IWriteLog writeLog =new WriteLogToSqlServer(); 4 //IWriteLog writeLog = new
      WriteLogToText();5 //把錯(cuò)誤信息寫到相應(yīng)的地方 6 writeLog.WriteLog(exceptionString);
      ?OK,大功告成,又可以去美滋滋了...

      星期三

      情景

      早晨,項(xiàng)目組長(zhǎng)再一次來到小明身邊,”經(jīng)過我的思考,我覺得把錯(cuò)誤信息同時(shí)寫到文本和數(shù)據(jù)庫(kù)中比較好“ ”為什么?“ “需求” “...”

      分析



      錯(cuò)誤信息有可能要寫到不同的地方,而且不知道有多少地方,說不定明天又加了一個(gè)Redis、后天再加一個(gè)....

      這時(shí)候我們可以考慮創(chuàng)建一個(gè)集合來保存都需要寫到那些地方去。(這里插一句:
      設(shè)計(jì)模式只是一種思想,實(shí)現(xiàn)方式肯定是不唯一的,但是思想是精髓,不能說這個(gè)代碼是這個(gè)模式,換一種方式實(shí)現(xiàn)就不是這個(gè)模式了。)

      然后依次寫入即可。

      開工

      對(duì)LogHelper進(jìn)行修改
      1 public class LogHelper 2 { 3 //添加一個(gè)靜態(tài)的異常信息隊(duì)列,只要出現(xiàn)異常就寫到隊(duì)列中。 4 public
      static Queue<string> ExceptionStringQueue = new Queue<string>(); 5 6 //
      定義一個(gè)集合來存放所有的 觀察者, 7 public static IList<IWriteLog> writeLogList = new
      List<IWriteLog>(); 8 9 //第一次用到該類型時(shí)會(huì)執(zhí)行靜態(tài)構(gòu)造函數(shù),只被執(zhí)行一次 10 static LogHelper() { 11
      12 //觀察(訂閱) 13 writeLogList.Add(new WriteLogToSqlServer()); 14 writeLogList.Add(
      new WriteLogToText()); 15 16 //創(chuàng)建一個(gè)線程池,將方法排入隊(duì)列以便執(zhí)行 17
      ThreadPool.QueueUserWorkItem(o=> { 18 while (true) 19 { 20 lock
      (ExceptionStringQueue)21 { 22 //如果有錯(cuò)誤信息寫入日志 23 if (ExceptionStringQueue.Count >
      0) 24 { 25 string exceptionString = ExceptionStringQueue.Dequeue(); 26 //發(fā)布 27
      foreach (var writeLog in writeLogList) 28 { 29
      writeLog.WriteLog(exceptionString);30 } 31 } 32 else 33 { 34 Thread.Sleep(
      1000); 35 } 36 } 37 } 38 39 }); 40 } 41 42 43 //給外部提供方法,將錯(cuò)誤信息寫入隊(duì)列 44 public
      static void Write(string exceptionString) { 45 lock (ExceptionStringQueue) 46 {
      47 //將錯(cuò)誤信息添加到隊(duì)列 48 ExceptionStringQueue.Enqueue(exceptionString); 49 } 50 }
      51 }
      后期如果還需要寫入其它地方或者去掉一個(gè)的話,只需要Add一個(gè)或者刪除一行即可。當(dāng)然,現(xiàn)在的代碼還有很多可優(yōu)化的地方,比如把通知者
      (LogHelper)進(jìn)行抽象,還可以通過配置文件加反射再次解耦。這里就不做過多介紹了。因?yàn)橐呀?jīng)星期四了...

      星期四

      采用Log4Net

      總結(jié)

      觀察者模式又叫發(fā)布-訂閱模式,定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者同時(shí)監(jiān)聽同一個(gè)對(duì)象。當(dāng)對(duì)象狀態(tài)發(fā)生改變時(shí),通知所訂閱的觀察者。

      什么時(shí)候使用?

      當(dāng)一個(gè)對(duì)象改變同時(shí)需要改變其他對(duì)象,并且還不知道要改變多少對(duì)象。這時(shí)應(yīng)該考慮觀察者模式。

      ?

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          亚洲经典视频 | 麻豆成人网址 | 丁香五月在线观看视频 | 亚洲最大的成人网站 | 黄色小视频大全 | 男女无遮挡120动态图有限公司 | 寡妇与男高潮hd片 | 午夜生活理论片 | 午夜黄色影视 | 人人草人人舔 |