最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入了解C#設計模式之訂閱發(fā)布模式

 更新時間:2020年06月24日 14:46:14   作者:HueiFeng  
這篇文章主要介紹了C#設計模式之訂閱發(fā)布模式的的相關資料,文中示例代碼非常詳細,供大家參考和學習,感興趣的朋友可以了解下

什么是Pub-Sub

發(fā)布訂閱是一種設計模式,它允許應用程序組件之間進行松散耦合。
其實訂閱發(fā)布設計中主要是發(fā)布者生成事件通道,用于在不了解任何訂閱者存在的情況下通知訂閱者。

當然委托EventHandlers和Event關鍵字在此事件處理機制中擔任著重要的角色。下面我們來看看如何使用它們。

Pub和Sub的使用

首先我們看一個簡單地訂閱發(fā)布模式.

定義一個Action委托,無返回值.

namespace PubSubPattern
{
  public class Pub
  {
    public Action OnChange { get; set; }

    public void Raise()
    {
      if (OnChange != null)
      {
        //Invoke OnChange Action
        OnChange();
      }
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      var p = new Pub();
      p.OnChange += () => Console.WriteLine("Sub 1");

      p.OnChange += () => Console.WriteLine("Sub 2");

      p.Raise();

      Console.WriteLine("Press enter !");
      Console.ReadLine();

    }
  }
}

如上代碼我們創(chuàng)建了一個發(fā)布者,并且我們調(diào)用委托進行創(chuàng)建我們匿名方法來訂閱。由于委托提供了多播功能,因此我們可以OnChange屬性上使用+=.

雖然說我們看著如上代碼執(zhí)行無誤,但是程序中仍然存在一些問題,如果使用=而不是+=,那么OnChange屬性中將會刪除第一個訂閱者。
由于OnChange是公共屬性,因此該類的任何外部用戶都可以進行調(diào)用p.OnChange().

使用Event關鍵字的發(fā)布訂閱

下面我們來看看使用event關鍵字后的代碼

  public class Pub
  {
    public event Action OnChange = delegate { };

    public void Raise()
    {
      OnChange();
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      Pub p = new Pub();
      p.OnChange += () => Console.WriteLine("Sub 1");
      p.OnChange += () => Console.WriteLine("Sub 2");
      p.Raise();
      Console.WriteLine("Press enter !");
      Console.ReadLine();
    }
  }

通過如上代碼我們試著去解決我們第一處所說的問題,我們會發(fā)現(xiàn)使用event關鍵字后可以保護我們OnChange免受不必要的訪問。它不允許使用=也就是說他不允許直接進行分配委托,因此我們現(xiàn)在可以避免使用=,從而避免應用程序不必要的麻煩。

可能大家也會發(fā)現(xiàn)OnChange初始化為空委托delegate{}。這樣可以確保我們的OnChange永遠不會為空。因為當我們其他進行對他調(diào)用的時候我們可以在代碼中進行刪除對他的非空檢查.

使用EventHandlers的發(fā)布訂閱

其實在訂閱發(fā)布中,發(fā)布者和訂閱者都不知道彼此的存在。有個EventHandler,它被稱為消息代理或者說事件總線,發(fā)布者和訂閱者都應該知道它,它接收所有傳入的消息并且將它們進行轉(zhuǎn)發(fā).

因此呢,在如下片段中我們使用EventHandler而不是用Action.

public delegate void EventHandler(
  object sender,
  EventArgs e
)

默認情況下,EventHandler將發(fā)送對象和一些事件參數(shù)作為參數(shù)。

 public class MyEventArgs : EventArgs
    {
      public int Value { get; set; }

      public MyEventArgs(int value)
      {
        Value = value;
      }
    }

    public class Pub
    {
      public event EventHandler<MyEventArgs> OnChange = delegate { };
      public void Raise()
      {
        OnChange(this, new MyEventArgs(1));
      }
    }
    class Program
    {
      static void Main(string[] args)
      {
        Pub p = new Pub();
        p.OnChange += (sender, e) => Console.WriteLine("Sub 1.Value:" + e.Value);
        p.OnChange += (sender, e) => Console.WriteLine("Sub 2.Value:" + e.Value);
        p.Raise();
        Console.WriteLine("Press enter !");
        Console.ReadLine();
      }
    }

如上代碼中通過pub類使用通用的EventHandler,它觸發(fā)EventHandler OnChange時需要傳遞的事件參數(shù)類型,在上面代碼片段中為MyArgs

事件中的異常

我們繼續(xù)說一種情況.大家看如下代碼片段

  public class MyEventArgs : EventArgs
  {
    public int Value { get; set; }

    public MyEventArgs(int value)
    {
      Value = value;
    }
  }

  public class Pub
  {
    public event EventHandler<MyEventArgs> OnChange = delegate { };
    public void Raise()
    {
      OnChange(this, new MyEventArgs(1));
    }
  }
  class Program
  {
    static void Main(string[] args)
    {
      Pub p = new Pub();
      p.OnChange += (sender, e) => Console.WriteLine("Sub 1.Value:" + e.Value);
      p.OnChange += (sender, e) => { throw new Exception(); };
      p.OnChange += (sender, e) => Console.WriteLine("Sub 2.Value:" + e.Value);
      p.Raise();
      Console.WriteLine("Press enter !");
      Console.ReadLine();
    }
  }

運行如上代碼后,大家會發(fā)現(xiàn)第一個訂閱者已經(jīng)執(zhí)行成功了,第二個訂閱者引發(fā)了異常,而第三個訂閱者未被調(diào)用.這是一個很尷尬的事情.

如果說我們覺得如上的過程不是我們預期的,我們需要手動引發(fā)事件并處理異常,這時候我們可以使用Delegate基類中定義的GetInvoctionList來幫助我們實現(xiàn)這些。

我們繼續(xù)看如下代碼

public class MyEventArgs : EventArgs
    {
      public int Value { get; set; }

      public MyEventArgs(int value)
      {
        Value = value;
      }
    }

    public class Pub
    {

      public event EventHandler<MyEventArgs> OnChange = delegate { };

      public void Raise()
      {
        MyEventArgs eventArgs = new MyEventArgs(1);

        List<Exception> exceptions = new List<Exception>();

        foreach (Delegate handler in OnChange.GetInvocationList())
        {
          try
          {
            handler.DynamicInvoke(this, eventArgs);
          }
          catch (Exception e)
          {
            exceptions.Add(e);
          }
        }

        if (exceptions.Any())
        {
          throw new AggregateException(exceptions);
        }
      }
    }
    class Program
    {
      static void Main(string[] args)
      {
        Pub p = new Pub();
        p.OnChange += (sender, e) => Console.WriteLine("Sub 1.Value:" + e.Value);
        p.OnChange += (sender, e) => { throw new Exception(); };
        p.OnChange += (sender, e) => Console.WriteLine("Sub 2.Value:" + e.Value);
        p.Raise();
        Console.WriteLine("Press enter !");
        Console.ReadLine();
      }
    }

Reference

https://github.com/hueifeng/DesignPatterns-Samples/tree/master/PubSubPattern

https://hackernoon.com/observer-vs-pub-sub-pattern-50d3b27f838c

以上就是深入了解C#設計模式之訂閱發(fā)布模式的詳細內(nèi)容,更多關于c# 訂閱發(fā)布模式的資料請關注腳本之家其它相關文章!

相關文章

  • 詳解c# 可空類型(Nullable)

    詳解c# 可空類型(Nullable)

    這篇文章主要介紹了c# 可空類型(Nullable)的相關資料,文中示例代碼非常詳細,幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07
  • C#連接SQL Server的實現(xiàn)方法

    C#連接SQL Server的實現(xiàn)方法

    這篇文章主要給大家介紹了關于C#連接SQL Server的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-12-12
  • C#?模式匹配完全指南

    C#?模式匹配完全指南

    模式匹配是一種高端的使用機制,它允許程序員在開發(fā)的時候以對象的類型作為條件篩選和分情況處理的一種手段,本文給大家介紹C#?模式匹配完全指南,感興趣的朋友跟隨小編一起看看吧
    2022-03-03
  • c# 曲線圖生成代碼

    c# 曲線圖生成代碼

    c# 曲線圖生成代碼,需要的朋友可以參考下。
    2011-07-07
  • 找到整型陣列中最大值和最小值的幾種方法總結(jié)

    找到整型陣列中最大值和最小值的幾種方法總結(jié)

    下面小編就為大家分享一篇找到整型陣列中最大值和最小值的幾種方法總結(jié),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • C#中ManualResetEvent用法總結(jié)

    C#中ManualResetEvent用法總結(jié)

    這篇文章主要介紹了C#中ManualResetEvent用法總結(jié),幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-01-01
  • C#仿密保卡功能的簡單實現(xiàn)代碼

    C#仿密保卡功能的簡單實現(xiàn)代碼

    昨天拿C#寫了個簡單的密??ǔ绦颍–onsole的,偷懶了一下 哈哈),實現(xiàn)了隨機生成5x5矩陣卡、轉(zhuǎn)換為字符串、從字符串讀取矩陣卡以及簡單驗證的功能
    2013-04-04
  • C#中方法的詳細介紹

    C#中方法的詳細介紹

    本篇文章介紹了,C#中方法的詳細說明。需要的朋友參考下
    2013-04-04
  • C#使用WebClient登錄網(wǎng)站并抓取登錄后的網(wǎng)頁信息實現(xiàn)方法

    C#使用WebClient登錄網(wǎng)站并抓取登錄后的網(wǎng)頁信息實現(xiàn)方法

    這篇文章主要介紹了C#使用WebClient登錄網(wǎng)站并抓取登錄后的網(wǎng)頁信息實現(xiàn)方法,涉及C#基于會話操作登陸網(wǎng)頁及頁面讀取相關操作技巧,需要的朋友可以參考下
    2017-05-05
  • C#使用NPOI將List數(shù)據(jù)導出到Excel文檔

    C#使用NPOI將List數(shù)據(jù)導出到Excel文檔

    這篇文章主要為大家詳細介紹了C#使用NPOI將List數(shù)據(jù)導出到Excel文檔,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02

最新評論

茌平县| 夏河县| 客服| 繁峙县| 光山县| 班戈县| 昌图县| 临洮县| 长顺县| 汉源县| 周口市| 栾城县| 恩施市| 新野县| 平乡县| 泾川县| 新宁县| 南丰县| 宁海县| 焦作市| 靖边县| 油尖旺区| 伊通| 东兰县| 中宁县| 三台县| 诸城市| 板桥市| 龙川县| 浮山县| 青川县| 鄂尔多斯市| 霍邱县| 扶绥县| 彩票| 桂林市| 五莲县| 双辽市| 萨嘎县| 沛县| 如东县|