C# 事件系統(一)


  每次過年在家的時候,都想着挖點坑.但是每次年后工作忙起來就在沒填過.今年照例挖坑.希望年后自己能填平.

  先說下事件.首先事件並不是局限的說那個關鍵字event.而是說這個需求實現的動作或者方向.當然這句表達的可能不太清楚.下面我會舉幾個例子.

  我們先想這樣一種場景.我們某個業務會一直運算處理一些數據,這時我們想暴露一些處理的狀態給外部,比如說處理完成了一批數據或者已經沒有數據可以處理的這種狀態.我們當然可以把這種狀態設置給某個屬性上暴露出來,但是這里會出現一個問題.就是外部應該在什么時候訪問這個屬性.

  這種場景很常見.比如你搶票的時候,訂單已經提交了.當沒有余票給你的時候,無論你怎么刷新頁面也不會有新的狀態給你.或者當你后台下載大文件的時候.不論你多久看一眼是否下載完成.都很難看一次就知道已經完成了.上面說的場景其實就是輪詢.通過不斷訪問來確定當前的狀態.那么最好的方式應該是當狀態改變時有某個機制通知我完成了.比如你搶票成功了有短信提醒,下載完成時有叮的一聲提示.

  通過上面的例子,我們自然會想到.當業務運行到某處需要通知外部時,調用一個方法通知外部即可.這也就是說事件其實是數據或狀態傳遞的一種方式.他是有方向的,由內部主動傳遞到外部.

  上面說道用一個方法通知外部,那么這個方法一定是外部的方法.在C#中當我們需要傳遞一個方法的時候,自然會想到Action,Func什么的,這些都是一種委托.這么看來那個event關鍵字就很容易理解了,通過這個關鍵字.我們對外暴露一個特殊的屬性.通過這個屬性,我們可以傳遞或者移除一個委托給內部.內部通過調用這個事件來間接的調用那些外部方法.

  如果讓我們設計一個事件的話,那么肯定是有一個容器,用來存儲多個委托.在用另外一個"東西"代表這個事件.當我們想觸發某個事件的,只需要通過那個"東西"來獲取那個東西代表的集合.然后依次調用委托即可.容器很好實現,C#內置的容器完全滿足我們的需求.這里我選擇的是HashSet而不是List.因為我的場景下有大量的插入與移除.List這種有序的集合在性能上不太適合.

  容器有了,那么那個"東西"我們就很好表示了.我們可以選擇任意一種數據來代替.比如int,enum,string等等.我在這里選擇的是string.主要因為懶.....當然也有其他的理由.使用Int沒有可讀性,當你想觸發一個事件時很難記起哪個數字是代表這個事件的.使用enum時每增加一個事件都要重新編輯一下enum.當然使用string也不是沒有壞處,就是如果你手誤了也不會有任何錯誤的提示.這個就需要跑測試或者通過其他的機制來規避了.

  以上扯了那么多,主要是為了闡明需求以及設計.后面會依次實現.

傳送門:

    C# 事件系統(一)

    C# 事件系統(二)

    C# 事件系統(三)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM