用 C 做元件設計時的事件實現方法討論

2021-05-07 11:13:21 字數 2298 閱讀 5919

事件,其實就是將物體的某個過程處理通過委託(delegate, 也就是函式指標) 的方式公開給外部的自定義函式處理。 c# 可以使用多播委託,但實際上一般情況下只需要用到單播。

事件需要通過呼叫到那個委託的**觸發才可以被呼叫。

以下用例子來說明。首先我們定義乙個委託:

namespace eventdemo

最簡單的事件定義方式:

namespace eventdemo

remove

}/// /// 觸發事件的某個方法

///

public void process()

public class1()

}}

class1 使用原始的事件定義方式, 有乙個問題,如果事件非常多的時候,每乙個事件都要對應乙個相應的私有的委託成員(函式指標)。在視窗程式裡尤其可怕,因為 windows 視窗訊息數以千計。這樣會造成很龐大的記憶體消耗。

這個模式需要改進為 class2。**如下:

namespace eventdemo

remove

}public event processhandler processend

remove

}public void process()

public class2()

}}

class2 中,每一種事件定義乙個相應的靜態變數作為他們在 hashtable 中的 keys.

hashtable 作為函式指標的容器,是私有的。

這樣實際上是 lazy allocate 模式,大大減小了記憶體的開銷。

但該實現也有問題,因為每個 key 只對應乙個 value,所以不能支援 multicast 的事件。

在 .net 中,通常繼承自 component 類來實現這種基礎架構。**如下:

namespace eventdemo

remove

}public void process()

public class3()

}}

component 類的實現是完整的,支援 multicast 委託。我們用 reflector 看一下該類的**,會看到有乙個叫做 eventhandlerlist 的類,**如下:

public sealed class eventhandlerlist : idisposable

public void addhandler(object key, delegate value)

else

}public void dispose()

private eventhandlerlist.listentry find(object key)

entry1 = entry1.next;

}return entry1;

}public void removehandler(object key, delegate value)

}// properties

public delegate this[object key]

return null;

}set

else}}

// fields

private listentry head;

// nested types

private sealed class listentry

// fields

internal delegate handler;

internal object key;

internal eventhandlerlist.listentry next;

}}

這個類實現了乙個事件的鍊錶資料結構。其中每乙個具體的事件是採用 delegate.combine(), delegate.remove() 方法來新增和刪除具體的 delegate. 所以這個的實現和 class2 的實現相比功能更加完整了。

component 類的**是這樣的:

[designercategory("component")]

public class component : marshalbyrefobject, icomponent, idisposable

return this.events;}}

// ...

}

它簡單的通過提供 events 這個屬性,讓設計者可以自由的實現各種屬性。

(注:本文的 class1 ~ class3 **範例來自黃忠成的《深入剖析 asp.net 元件設計》一書。)

用C 做ActiveX 的方法

原文在 步驟1 建立乙個新的 windows窗體控制項庫 專案 2 在assemblyinfo.cs中引用system.security命名空間,並新增一句 assembly allowpartiallytrustedcallers 4 winform控制項轉換為activex控制項 選中 使程式集...

設計模式 模板方法的C 實現

這是bwar在2009年寫的設計模式c 實現,均可編譯可執行,一直存在自己的電腦裡,曾經在團隊技術分享中分享過,現搬到線上來。1.1 目的 定義乙個操作中的演算法骨架,而將一些步驟延遲到子類中。templatemethod使得子類可以不改變乙個演算法的結構即可重定義該演算法的某些特定步驟。1.2 適...

用C 控制Windows系統音量的實現方法

c 開發windows應用程式中經常需要去控制系統的音量,分兩種方式 1.使用win api控制 2.使用c dll控制 win api控制 使用user32.dll程式設計客棧和winmm.dll都可以控制系統音量,區別是win系統的版本。winmm.dll xp環境下可用,user32.dll ...