<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      非常好玩的C#/.NET 基礎(chǔ) -- 安全有效引發(fā)事件

      最近在網(wǎng)上看到一篇很好的文章, 討論如何安全有效的引發(fā)事件.

      也許你不一定要用到下面相同的解決方案, 但是至少你應(yīng)該知道在引發(fā)事件時(shí)候需要考慮的問題.

      引發(fā)事件的問題

      引發(fā)事件是一個(gè)非常容易的事情, 但是的確也有它的誤區(qū). 讓我們舉個(gè)例子. 假設(shè)我們寫個(gè)消息接收器, 每當(dāng)我們收到一個(gè)新消息, 我們引發(fā)一個(gè)包含了新消息的事件 MessageReceived.

      安裝我們通常的方法,就是:

      public class MessageReceivedEventArgs : EventArgs
      {
      // 接收到的消息
      public string Message { get; private set; }

      // 架構(gòu) ReceivedEventArgs
      public MessageReceivedEventArgs(string message)
      {
      Message = message;
      }
      }

      接下來, 我們創(chuàng)建一個(gè)非線程安全訪問的類UnsafeMessenger來實(shí)現(xiàn)這個(gè)消息同時(shí)通知所有的訂閱者(subscriber).

      public class UnsafeMessenger
      {
      public event EventHandler<MessageReceivedEventArgs> MessageReceived;

      // 當(dāng)收到新消息時(shí)調(diào)用
      public void OnNewMessage(string message)
      {
      if (MessageReceived != null)
      {
      MessageReceived(this, new MessageReceivedEventArgs(message));
      }
      }
      }

      注意, 通常OnNewMessage() 是私有的, 但是在這里為了測(cè)試的方便,我們將它設(shè)為public.

       

      大功告成!! 是嗎? 事實(shí)上, 如果我們是單線程的程序, 這的確已經(jīng)足夠, 但是這是非線程安全訪問(thread-safe).

      為什么? 想想, 訂閱者可以任何時(shí)候訂閱或者取消訂閱. 比如,我們當(dāng)前有一個(gè)訂閱者, 那么當(dāng)接收到一個(gè)新消息,執(zhí)行到這一句時(shí):

      if (MessageReceived != null)
      肯定會(huì)通過, 因?yàn)橛幸粋€(gè)訂閱者, 如果這個(gè)時(shí)候, 這名訂閱者執(zhí)行了取消訂閱的命令:
      myMessenger.MessageReceived -= MyMessageHandler;
       
      那么MessageReceived委托 就為null 了, 

       


      //已經(jīng)通過了這個(gè)IF語句

      if (MessageReceived != null)
      {
      //MessageReceived委托 就為null 了, 但是我們將要執(zhí)行這句
      MessageReceived(this, new MessageReceivedEventArgs(message));
      }

      這個(gè)時(shí)候, 就會(huì)引發(fā)NullReferenceException.

       

      方案一: 鎖住它, 鎖機(jī)制

      當(dāng)允許多線程的時(shí)候, 我們可以用鎖機(jī)制來避免一個(gè)用戶在我們執(zhí)行事件時(shí)訂閱或者取消訂閱, 或者在用戶執(zhí)行操作時(shí), 不能引發(fā)事件.


      public class SyncronizedMessenger : IMessenger
      {
      // 委托和鎖
      private EventHandler<MessageReceivedEventArgs> _messageReceived;
      private readonly object _raiseLock = new object();

      // 訂閱/取消訂閱的鎖機(jī)制
      public event EventHandler<MessageReceivedEventArgs> MessageReceived
      {
      add { lock (_raiseLock) { _messageReceived += value; } }
      remove { lock (_raiseLock) { _messageReceived -= value; } }
      }



      // 引發(fā)事件的鎖機(jī)制

      public void OnNewMessage(string message)
      {
      lock (_raiseLock)
      {
      if (_messageReceived != null)
      {
      _messageReceived(this, new MessageReceivedEventArgs(message));
      }
      }
      }

      }
      這樣, 如果有人試圖訂閱或取消訂閱時(shí), 必須要等待OnNewMessage事件的完成, 反之亦然.
       
       

      方案二: 永不為空, 默認(rèn)加載一個(gè)訂閱者

      我們面臨的主要問題是有可能委托為空. 那么如果事先加載一個(gè)委托,會(huì)怎么樣?


      public class EmptySubscriberMessenger : IMessenger
      {

      // 立刻給它一個(gè)空的訂閱者
      public event EventHandler<MessageReceivedEventArgs> MessageReceived = (s, e) => { };


      // 現(xiàn)在根本無需檢查是否為 null!
      public void OnNewMessage(string message)
      {
      MessageReceived(this, new MessageReceivedEventArgs(message));
      }

      }

      方案三: 創(chuàng)建一個(gè)本地的委托副本

      另外一個(gè)簡(jiǎn)單的方案, 也就是很多人都在使用的, 微軟建議的模式: 創(chuàng)建一個(gè)本地的委托副本.


      public class LocalCopyMessenger : IMessenger
      {
      public event EventHandler<MessageReceivedEventArgs> MessageReceived;


      // 當(dāng)我們引發(fā)事件時(shí), 做一個(gè)副本
      public void OnNewMessage(string message)
      {
      var target = MessageReceived;

      if (target != null)
      {
      target(this, new MessageReceivedEventArgs(message));
      }
      }
      }

      下面是以上四種方法的效率, 在執(zhí)行10億次的重復(fù)操作時(shí):

      ScreenShot074

       

      以上參考翻譯自:  C#/.NET Fundamentals: Safely and Efficiently Raising Events

      小結(jié)

      有一種編程方式叫 Cargo Cult Programming, 中文名:  貨物崇拜編程. 維基定義為"

      其特征為不明就里地儀式性地使用代碼或程序架構(gòu)。貨物崇拜編程通常是一個(gè)程序員既沒理解他要解決的 bug,也沒理解表面上的解決方案的典型表現(xiàn)。

      這個(gè)名詞有時(shí)也指不熟練的或沒經(jīng)驗(yàn)的程序員從某處拷貝代碼到另一處,卻不太清楚其代碼是如何工作的,或者不清楚在新的地方是否需要這段代碼。也可以指不正確或過份的應(yīng)用設(shè)計(jì)模式,代碼風(fēng)格或編程方法,卻對(duì)其原理不明就里。"

      我承認(rèn)在"高舉實(shí)用主義"(敝人的如何做一個(gè)快樂的ASP.NET程序員) 的年代, 為了效率, 我也經(jīng)常這樣做.--試問誰有時(shí)間給第三方控件做測(cè)試?

      自從這個(gè)創(chuàng)建本地委托副本的方案被大牛們推薦后, 大家都在用, 有人也不一定明白它背后的故事.

      有時(shí)間的朋友們聊聊.net中的野史, 談笑間擴(kuò)充一點(diǎn)編程的能力,總比聊哪個(gè)明星又被潛規(guī)則了要有益處. 哈哈~~~

      本年總結(jié) + 新年祝福

      有可能是本年最后一篇下面是我今天博文的部分列表, 先祝大家新的一年快樂!

       

      * 程序員人生

      有些時(shí)候,作為程序員,我們只是需要被重啟一下

      碼斗士的修煉之路 -- 如何保持并提升戰(zhàn)斗力

      如何做一個(gè)快樂的ASP.NET程序員

       

      * C# 語言

      寫出優(yōu)雅簡(jiǎn)明代碼的論題集 -- Csharp(C#)篇[1]

      寫出優(yōu)雅簡(jiǎn)明代碼的論題集 -- Csharp(C#)篇[2]

      再說Csharp(C#) ”整潔代碼”那些事 -- 變小[1]

       

      C# 中奇妙的函數(shù)–8. String Remove() 和 Replace()

      C# 中奇妙的函數(shù)–7. String Split 和 Join

      C# 中奇妙的函數(shù)–6. 五個(gè)序列聚合運(yùn)算(Sum, Average, Min, Max,Aggregate)

      C# 中奇妙的函數(shù)–5. Nullable 靜態(tài)類

      C# 中奇妙的函數(shù) -- 4. Empty, DefaultIfEmpty, Count

      C# 中奇妙的函數(shù) -- 3. 聯(lián)接序列的五種簡(jiǎn)單方法

      C# 中奇妙的函數(shù) -- 2. First 和 Single -- 你是她心中的第一還是唯一?

      C# 中奇妙的函數(shù) -- 1. ToLookup

       

      不可不知的C#基礎(chǔ) 4. 延遲加載 -- 提高性能

      不可不知的C#基礎(chǔ) 3. 線程淺析

      不可不知的C#基礎(chǔ) 2. -–從 struct 和 class的異同 說開去

      不可不知的C#基礎(chǔ) 1. -- Extension 擴(kuò)展方法

       

      * 其他

      從 Comparison/Converter 到Func 的進(jìn)化

      從 Linq Queries 快速生成數(shù)據(jù) HTML, EXCEL, CSV 報(bào)表

      DynamicXml -- 動(dòng)態(tài)讀取操作XML (一個(gè)從XML到Object的通用實(shí)現(xiàn))

      posted @ 2011-12-21 07:15  擁有的都是恩典  閱讀(7947)  評(píng)論(19)    收藏  舉報(bào)
      主站蜘蛛池模板: 四虎国产精品永久入口| 潘金莲高清dvd碟片| 国产精品午夜福利资源| h动态图男女啪啪27报gif| 乱码精品一区二区三区 | 国产精品自拍午夜福利| 欧美牲交a欧美牲交aⅴ免费真| 欧美自拍另类欧美综合图片区| 亚洲午夜性猛春交xxxx| 撩起胸让我的?蹭来蹭去| 在线视频中文字幕二区| 久久久精品2019中文字幕之3| 日韩精品国产二区三区| 99久久免费精品国产色| 久久精品国产6699国产精 | 视频一区二区三区刚刚碰| 华人在线亚洲欧美精品| 国产精品亚韩精品无码a在线| 中文字幕av中文字无码亚| 国产午夜福利小视频在线| 久久婷婷综合色丁香五月| 精品久久精品午夜精品久久| 久久国产成人高清精品亚洲| 国产精品自拍中文字幕| 1024你懂的国产精品| 日韩av毛片福利国产福利| 亚洲一区二区三区在线播放无码| 亚洲欧美在线一区中文字幕| 日韩精品专区在线影观看| 风韵丰满熟妇啪啪区老老熟妇| 亚洲日韩一区二区| 日本九州不卡久久精品一区| 国产jlzzjlzz视频免费看| 非会员区试看120秒6次| 亚洲av激情一区二区三区| 国产永久免费高清在线观看| 亚洲一区二区三区啪啪| 中文字幕国产在线精品| 国产欧美日韩综合精品二区| 亚洲国产精品一区在线看| 欧美丰满熟妇xxxx性|