網站首頁 編程語言 正文
IDisposable是.net中的主動資源釋放接口,它是在編程過程中經常使用到的一個接口,本文介紹一下微軟在Rx.NET中提供的一系列常用的Disposable類,通過它們可以簡化我們的程序代碼,提高代碼質量。
IDisposable:
一個簡單的IDisposable接口實現如下
class DisposableObject : IDisposable
{
private readonly string name = null;
public DisposableObject(string name)
{
this.name = name;
}
public void Dispose()
{
Console.WriteLine("{0} - Disposed", this.name);
}
}
注: 這個例子并不是合適的實現,主要是為了后面的代碼演示使用。
ICancelable
RX框架在Disposable接口上擴展了一下,增加了一個查看是否被釋放的狀態,定義了一個ICancelable接口
public interface ICancelable : IDisposable
{
bool IsDisposed { get; }
}
除了Disposable.Empty外,RX框架提供的都是ICancelable接口對象。
Disposable.Empty
Disposable.Empty返回的是一個沒有任何功能的IDisposable對象,是一個IDisposable的NullObject模式的實現。
它的Dispose函數可以使用,但沒有任何行為。
Disposable.Create
Disposable.Create可以快速構建一個IDisposable對象,它接受一個委托,當Dispose函數調用時,執行該委托。
var d = Disposable.Create(() =>
{
Console.WriteLine("Disposed");
});
d.Dispose();
BooleanDisposable
BooleanDisposable是一個簡單的ICancelable的實現,它的Dispose操作也沒有任何行為,但可以查看該函數是否執行過。
var d = new BooleanDisposable();
Console.WriteLine(d.IsDisposed);
d.Dispose();
Console.WriteLine(d.IsDisposed);
由于不能控制該對象的Dispose行為,這個對象用得到不是很多,往往用來作為一個開關變量使用。
CancellationDisposable
CancellationDisposable可將一個CancellationTokenSource對象封裝為Disposable對象
- 當Dispose函數調用時,調用Cancel函數。
- 查看IsPosed狀態時,返回IsCancellationRequested狀態
簡單的示例如下:
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對象,不過它是一個引用計數型的封裝。
- 新建RefCountDisposable對象后,引用計數為1
- 調用GetDisposable可以生成一個新的引用Disposable封裝,引用技術加1
- 調用RefCountDisposable對象和GetDisposable生成的Disposable對象時,引用計數都減1
- 引用計數為0時,釋放封裝的Disposable對象
這里需要注意的時,當調用RefCountDisposable. Dispose函數時,可能引用計數還不為0,此時還是可以繼續調用GetDisposable函數增加引用計數的。
簡單的示例如下:
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();
這個類在釋放共享資源的時候非常有用,例如我們做視頻點播的時候,當有多個客戶端點播視頻時,每個客戶端都需要維護引用計數,當所有客戶端都退出的時候,會自動Dispose,注銷視頻源。
CompositeDisposable
CompositeDisposable用于聚合多個disposable對象,形成一個新的disposable對象,它主要有Add,Clear,Dispose三個函數。
- Add函數將子Disposable對象添加到集合
- Clear函數刪除集合類所有的Disposable對象,同時調用子Disposable對象的Dispose函數
- Dispose函數釋放CompositeDisposable對象:釋放所有子Disposable對象。
- 如果CompositeDisposable對象已經釋放,再次調用Add函數時,不會添加到集合,而是直接調用其子對象的Dispose函數。
簡單的示例如下:
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對象也是一個復合Disposable對象
- 它主要用于封裝一個Disposable對象,將其與一個SynchronizationContext上下文關聯,
- 封裝后生成的ContextDisposable對象的Disposable函數會Post到上下文線程中執行。
簡單的示例如下:
var context = SynchronizationContext.Current;
var obj = new DisposableObject("#1");
var d = new ContextDisposable(context, obj);
d.Dispose();
這個對象用于釋放UI對象非常方便,另外,也可以實現用于將一些Dispose函數推送到指定的隊列中串行執行,從而避免一些并發問題。
ScheduledDisposable
ScheduledDisposable和ContextDisposable類似,也是用于封裝一個Disposable對象,不過它是將其Dispose函數推送到指定的IScheduler中執行。
var scheduler = ThreadPoolScheduler.Instance;
var obj = new DisposableObject("#1");
var d = new ScheduledDisposable(scheduler, obj);
d.Dispose();
SingleAssignmentDisposable
SingleAssignmentDisposable是一個關聯型的Disposable對象
- 可以通過它的Disposable屬性關聯到子Dispose對象。
- 當執行Dispose函數時,執行的是子Dispose對象的Dispose函數,如果沒有關聯子Dispose對象,則不執行任何操作。
- 已經執行Dispose函數后,再次使用Disposable屬性關聯后無法關聯,直接會調用子對象的Dispose函數。
SingleAssignmentDisposable的關聯有一個Single特點,它主要體現為:
- 如果已經通過Disposable屬性關聯后,再次調用Disposable屬性關聯時會拋異常
簡單的示例如下:
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");
輸出結果為:
Disposable has already been assigned.
#1 – Disposed
#3 - Disposed
MultipleAssignmentDisposable
MultipleAssignmentDisposable和SingleAssignmentDisposable類似,區別是其關聯的multi特性,它的特點是:
- 如果已經通過Disposable屬性關聯后,再次調用Disposable屬性是會覆蓋關聯
簡單的示例如下:
var d = new MultipleAssignmentDisposable();
d.Disposable = new DisposableObject("#1");
d.Disposable = new DisposableObject("#2");
d.Dispose();
d.Disposable = new DisposableObject("#3");
輸出結果為:
#2 – Disposed
#3 - Disposed
SerialDisposable
SerialDisposable和SingleAssignmentDisposable也類似,不過它的Disposable屬性再次關聯的策略是:
- 覆蓋關聯,同時先釋放上一個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();
輸出結果為:
#1 – Set
#2 – Set
#1 – Disposed
Dispose
#2 – Disposed
#3 – Set
#3 - Disposed
原文鏈接:https://www.cnblogs.com/TianFang/p/9096001.html
相關推薦
- 2022-06-20 Flutter路由守衛攔截的實現_Android
- 2023-07-13 css 為什么要清除浮動
- 2022-03-17 C#實現多文件打包壓縮(.Net?Core)_C#教程
- 2023-03-18 詳解Flutter中key的正確使用方式_Android
- 2022-06-13 Docker鏡像的commit操作示例及作用_docker
- 2022-10-25 idea resources和webapp下面的文件不編譯怎么辦?
- 2022-05-26 C/C++調用Fortran的DLL的操作過程_C 語言
- 2022-07-28 Python實現Word文檔樣式批量處理_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支