Rx.NET庫中IDisposable對象的用法
IDisposable是.net中的主動資源釋放接口,它是在編程過程中經(jīng)常使用到的一個接口,本文介紹一下微軟在Rx.NET中提供的一系列常用的Disposable類,通過它們可以簡化我們的程序代碼,提高代碼質(zhì)量。
IDisposable:
一個簡單的IDisposable接口實現(xiàn)如下
class DisposableObject : IDisposable { private readonly string name = null; public DisposableObject(string name) { this.name = name; } public void Dispose() { Console.WriteLine("{0} - Disposed", this.name); } }
注: 這個例子并不是合適的實現(xiàn),主要是為了后面的代碼演示使用。
ICancelable
RX框架在Disposable接口上擴展了一下,增加了一個查看是否被釋放的狀態(tài),定義了一個ICancelable接口
public interface ICancelable : IDisposable { bool IsDisposed { get; } }
除了Disposable.Empty外,RX框架提供的都是ICancelable接口對象。
Disposable.Empty
Disposable.Empty返回的是一個沒有任何功能的IDisposable對象,是一個IDisposable的NullObject模式的實現(xiàn)。
它的Dispose函數(shù)可以使用,但沒有任何行為。
Disposable.Create
Disposable.Create可以快速構(gòu)建一個IDisposable對象,它接受一個委托,當Dispose函數(shù)調(diào)用時,執(zhí)行該委托。
var d = Disposable.Create(() => { Console.WriteLine("Disposed"); }); d.Dispose();
BooleanDisposable
BooleanDisposable是一個簡單的ICancelable的實現(xiàn),它的Dispose操作也沒有任何行為,但可以查看該函數(shù)是否執(zhí)行過。
var d = new BooleanDisposable(); Console.WriteLine(d.IsDisposed); d.Dispose(); Console.WriteLine(d.IsDisposed);
由于不能控制該對象的Dispose行為,這個對象用得到不是很多,往往用來作為一個開關(guān)變量使用。
CancellationDisposable
CancellationDisposable可將一個CancellationTokenSource對象封裝為Disposable對象
- 當Dispose函數(shù)調(diào)用時,調(diào)用Cancel函數(shù)。
- 查看IsPosed狀態(tài)時,返回IsCancellationRequested狀態(tài)
簡單的示例如下:
var source = new CancellationTokenSource(); source.Token.Register(() => Console.WriteLine("Cancelled")); var d = new CancellationDisposable(source); Console.WriteLine(d.IsDisposed); Console.WriteLine(source.IsCancellationRequested);
RefCountDisposable
RefCountDisposable也是一個封裝型的Disposable對象,不過它是一個引用計數(shù)型的封裝。
- 新建RefCountDisposable對象后,引用計數(shù)為1
- 調(diào)用GetDisposable可以生成一個新的引用Disposable封裝,引用技術(shù)加1
- 調(diào)用RefCountDisposable對象和GetDisposable生成的Disposable對象時,引用計數(shù)都減1
- 引用計數(shù)為0時,釋放封裝的Disposable對象
這里需要注意的時,當調(diào)用RefCountDisposable. Dispose函數(shù)時,可能引用計數(shù)還不為0,此時還是可以繼續(xù)調(diào)用GetDisposable函數(shù)增加引用計數(shù)的。
簡單的示例如下:
var d = new RefCountDisposable(new DisposableObject("#1")); var ref1 = d.GetDisposable(); var ref2 = d.GetDisposable(); Console.WriteLine("ref2 - Dispose"); ref2.Dispose(); Console.WriteLine("ref1 - Dispose"); ref1.Dispose(); Console.WriteLine("Dispose"); d.Dispose();
這個類在釋放共享資源的時候非常有用,例如我們做視頻點播的時候,當有多個客戶端點播視頻時,每個客戶端都需要維護引用計數(shù),當所有客戶端都退出的時候,會自動Dispose,注銷視頻源。
CompositeDisposable
CompositeDisposable用于聚合多個disposable對象,形成一個新的disposable對象,它主要有Add,Clear,Dispose三個函數(shù)。
- Add函數(shù)將子Disposable對象添加到集合
- Clear函數(shù)刪除集合類所有的Disposable對象,同時調(diào)用子Disposable對象的Dispose函數(shù)
- Dispose函數(shù)釋放CompositeDisposable對象:釋放所有子Disposable對象。
- 如果CompositeDisposable對象已經(jīng)釋放,再次調(diào)用Add函數(shù)時,不會添加到集合,而是直接調(diào)用其子對象的Dispose函數(shù)。
簡單的示例如下:
var d = new CompositeDisposable(); d.Add(new DisposableObject("#1")); d.Add(new DisposableObject("#2")); d.Add(new DisposableObject("#3")); d.Clear(); Console.WriteLine("----------"); d.Add(new DisposableObject("#4")); d.Add(new DisposableObject("#5")); d.Add(new DisposableObject("#6")); d.Dispose(); Console.WriteLine("----------"); d.Add(new DisposableObject("#7"));
ContextDisposable
ContextDisposable對象也是一個復(fù)合Disposable對象
- 它主要用于封裝一個Disposable對象,將其與一個SynchronizationContext上下文關(guān)聯(lián),
- 封裝后生成的ContextDisposable對象的Disposable函數(shù)會Post到上下文線程中執(zhí)行。
簡單的示例如下:
var context = SynchronizationContext.Current; var obj = new DisposableObject("#1"); var d = new ContextDisposable(context, obj); d.Dispose();
這個對象用于釋放UI對象非常方便,另外,也可以實現(xiàn)用于將一些Dispose函數(shù)推送到指定的隊列中串行執(zhí)行,從而避免一些并發(fā)問題。
ScheduledDisposable
ScheduledDisposable和ContextDisposable類似,也是用于封裝一個Disposable對象,不過它是將其Dispose函數(shù)推送到指定的IScheduler中執(zhí)行。
var scheduler = ThreadPoolScheduler.Instance; var obj = new DisposableObject("#1"); var d = new ScheduledDisposable(scheduler, obj); d.Dispose();
SingleAssignmentDisposable
SingleAssignmentDisposable是一個關(guān)聯(lián)型的Disposable對象
- 可以通過它的Disposable屬性關(guān)聯(lián)到子Dispose對象。
- 當執(zhí)行Dispose函數(shù)時,執(zhí)行的是子Dispose對象的Dispose函數(shù),如果沒有關(guān)聯(lián)子Dispose對象,則不執(zhí)行任何操作。
- 已經(jīng)執(zhí)行Dispose函數(shù)后,再次使用Disposable屬性關(guān)聯(lián)后無法關(guān)聯(lián),直接會調(diào)用子對象的Dispose函數(shù)。
SingleAssignmentDisposable的關(guān)聯(lián)有一個Single特點,它主要體現(xiàn)為:
- 如果已經(jīng)通過Disposable屬性關(guān)聯(lián)后,再次調(diào)用Disposable屬性關(guān)聯(lián)時會拋異常
簡單的示例如下:
var d = new SingleAssignmentDisposable(); d.Disposable = new DisposableObject("#1"); try { d.Disposable = new DisposableObject("#2"); //--- 例外発生 } catch (InvalidOperationException ex) { Console.WriteLine(ex.Message); } d.Dispose(); d.Disposable = new DisposableObject("#3");
輸出結(jié)果為:
Disposable has already been assigned.
#1 – Disposed
#3 - Disposed
MultipleAssignmentDisposable
MultipleAssignmentDisposable和SingleAssignmentDisposable類似,區(qū)別是其關(guān)聯(lián)的multi特性,它的特點是:
- 如果已經(jīng)通過Disposable屬性關(guān)聯(lián)后,再次調(diào)用Disposable屬性是會覆蓋關(guān)聯(lián)
簡單的示例如下:
var d = new MultipleAssignmentDisposable(); d.Disposable = new DisposableObject("#1"); d.Disposable = new DisposableObject("#2"); d.Dispose(); d.Disposable = new DisposableObject("#3");
輸出結(jié)果為:
#2 – Disposed
#3 - Disposed
SerialDisposable
SerialDisposable和SingleAssignmentDisposable也類似,不過它的Disposable屬性再次關(guān)聯(lián)的策略是:
- 覆蓋關(guān)聯(lián),同時先釋放上一個Disposable對象。
簡單的示例如下:
var d = new SerialDisposable(); Console.WriteLine("#1 - Set"); d.Disposable = new DisposableObject("#1"); Console.WriteLine("#2 - Set"); d.Disposable = new DisposableObject("#2"); Console.WriteLine("Dispose"); d.Dispose();
輸出結(jié)果為:
#1 – Set
#2 – Set
#1 – Disposed
Dispose
#2 – Disposed
#3 – Set
#3 - Disposed
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#實現(xiàn)HTTP協(xié)議迷你服務(wù)器(兩種方法)
用C#語言實現(xiàn)HTTP協(xié)議的服務(wù)器類本文將以兩種稍微有差別的方式用C#語言實現(xiàn);要完成高性能的Web服務(wù)功能,通常都是需要寫入到服務(wù),如IIS,Apache Tomcat感興趣的朋友可以了解下,或許對你學習c#有所幫助2013-02-02異步 HttpContext.Current實現(xiàn)取值的方法(解決異步Application,Session,Cache.
在一個項目中,為了系統(tǒng)執(zhí)行效率更快,把一個經(jīng)常用到的數(shù)據(jù)庫表通過dataset放到Application中,發(fā)現(xiàn)在異步實現(xiàn)中每一次都會出現(xiàn)HttpContext.Current為null的異常,后來在網(wǎng)上查了好多資料,發(fā)現(xiàn)問這個問題的人多,回答的少2009-07-07asp.net MVC實現(xiàn)無組件上傳圖片實例介紹
無組件實現(xiàn)上傳圖片使用input的file作為上傳選擇文件,具體實現(xiàn)如下:前后臺代碼很詳細,感興趣的朋友們可不要錯過了哈2013-05-05ASP.NET Core3.x API版本控制的實現(xiàn)
這篇文章主要介紹了ASP.NET Core3.x API版本控制的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-06-06ASP.NET中Web.config文件的層次關(guān)系詳細介紹
Web.config 是一個基于 XML 的配置文件,該文件的作用是對應(yīng)用程序進行配置,下面為大家介紹下ASP.NET中Web.config文件的層次關(guān)系2014-01-01