2012-08-02 23 views
0

我有F#代碼看起來像這樣:自誤差依賴自處置的IObservable訂閱

module O = Control.Observable 
//... 
use ss = serve' 4000 
     |> O.subscribe 
      (fun c -> use cs = RSS.items 
           |> O.subscribe (bytes >> c.SendAll) |> ignore) 

其中

serve' : int -> IObservable<Socket> 
c   : Socket 
RSS.items : IObservable<XElement> 
bytes  : XElement -> byte [] 
c.SendAll : byte [] -> unit 
  • 什麼是最地道的方式保留cs,直到c.SendAll失敗?
  • 是否存在或是否可以定義Observable.subscribeUntilError(action)如果action失敗,訂閱將被處置;否則action運行只要IObservable不斷推動?
+2

當observable通過「OnComplete」或「OnError」完成時,訂閱會自動處理。如果您想提前終止,您只需要處理訂閱。 – Enigmativity 2012-08-02 02:57:44

+0

@Enigmativity哦,如果沒有明確處置,他們*是否堅持*但只是超出了範圍?這將解釋爲什麼'忽略'似乎不會讓他們垃圾回收,爲什麼我的上述代碼類型的作品。 – 2012-08-02 03:25:56

+0

它們就像任何.NET對象 - 如果它們超出範圍,並且沒有引用留給它們,那麼它們將被GC化。 – Enigmativity 2012-08-02 04:58:54

回答

0

我想出了這一點:

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存在。