我想出了這一點:
let inline Δ<'a> = Unchecked.defaultof<'a>
let inline LOG x = printf "%A" x
module O = Observable
let d = ref (Δ:IDisposable)
let b x = try a x with e -> LOG e; let s = !d in if s <> Δ then s.Dispose()
d := o |> O.subscribe b
{
new IDisposable with
member x.Dispose() = let s = !d in if s <> Δ then d := Δ; s.Dispose()
}
爲了展示差別,嘗試在main
!
使用subscribe
:
use s = new Subject<int>()
use x = s |> O.subscribe (fun _ -> raise <| Exception())
use y = s |> O.subscribe (printf "%i")
s.OnNext 20
應用程序自帶轟然倒下:
Unhandled Exception: System.Exception: Exception of type 'System.Exception' was thrown.
at Microsoft.FSharp.Core.Operators.Raise[T](Exception exn)
at [email protected](Int32 _arg1) in C:\Eniox\Eniox.News.Google\Eniox.News.Google\Program.fs:line 60
at [email protected]1915.System-IObserver`1-OnNext(T value)
at System.Reactive.Observer`1.OnNext(T value)
at System.Reactive.Subjects.Subject`1.OnNext(T value)
at Program.System.main(String[] args) in C:\Eniox\Eniox.News.Google\Eniox.News.Google\Program.fs:line 606
現在使用subscribeUE
:
use s = new Subject<int>()
use x = s |> O.subscribeUE (fun _ -> raise <| Exception())
use y = s |> O.subscribe (printf "%i")
s.OnNext 20
愉快地處理訂閱x
,應用程序繼續無故障運行並正常退出!輸出與LOG = ignore
:
20
我很想知道是否類似的功能居然我覺得這個組合子太有用的離開了某處RX 2.0存在。
當observable通過「OnComplete」或「OnError」完成時,訂閱會自動處理。如果您想提前終止,您只需要處理訂閱。 – Enigmativity 2012-08-02 02:57:44
@Enigmativity哦,如果沒有明確處置,他們*是否堅持*但只是超出了範圍?這將解釋爲什麼'忽略'似乎不會讓他們垃圾回收,爲什麼我的上述代碼類型的作品。 – 2012-08-02 03:25:56
它們就像任何.NET對象 - 如果它們超出範圍,並且沒有引用留給它們,那麼它們將被GC化。 – Enigmativity 2012-08-02 04:58:54