我想补充一下
public static IObservable<TSource> Create<TSource>(
Func<IObserver<TSource>, Action> subscribe)
{...}
在F#中使用,以便不是使用函数或动作调用,而是使用标准F#类型,即IObserver -> (unit -> unit)
。
我该如何做到这一点?
编辑:
添加完整示例。不确定为什么obsAction
不起作用。
open System
open System.Reactive
open System.Reactive.Disposables
open System.Reactive.Linq
type Observable with
static member Create(subscribe) =
Observable.Create(fun observer -> Action(subscribe observer))
let obsDispose (observer:IObserver<_>) =
let timer = new System.Timers.Timer()
timer.Interval <- 1000.00
let handlerTick = new Timers.ElapsedEventHandler(fun sender args -> observer.OnNext("tick"))
let handlerElapse = new Timers.ElapsedEventHandler(fun sender args -> printfn "%A" args.SignalTime)
timer.Elapsed.AddHandler(handlerTick)
timer.Elapsed.AddHandler(handlerElapse)
timer.Start()
Disposable.Empty
let obsAction (observer:IObserver<_>) =
let timer = new System.Timers.Timer()
timer.Interval <- 1000.00
let handlerTick = new Timers.ElapsedEventHandler(fun sender args -> observer.OnNext("tick"))
let handlerElapse = new Timers.ElapsedEventHandler(fun sender args -> printfn "%A" args.SignalTime)
timer.Elapsed.AddHandler(handlerTick)
timer.Elapsed.AddHandler(handlerElapse)
timer.Start()
let action() =
timer.Elapsed.RemoveHandler(handlerTick)
timer.Elapsed.RemoveHandler(handlerElapse)
timer.Dispose()
action
let obsOtherAction (observer:IObserver<_>) =
let timer = new System.Timers.Timer()
timer.Interval <- 1000.00
let handlerTick = new Timers.ElapsedEventHandler(fun sender args -> observer.OnNext("tick"))
let handlerElapse = new Timers.ElapsedEventHandler(fun sender args -> printfn "%A" args.SignalTime)
timer.Elapsed.AddHandler(handlerTick)
timer.Elapsed.AddHandler(handlerElapse)
timer.Start()
new System.Action( fun () ->
timer.Elapsed.RemoveHandler(handlerTick)
timer.Elapsed.RemoveHandler(handlerElapse)
timer.Dispose())
let worksNeverStops = obsDispose |> Observable.Create |> Observable.subscribe(fun time -> printfn "Time: %A" time)
let actionWorks = obsOtherAction |> Observable.Create |> Observable.subscribe(fun time -> printfn "Time: %A" time)
let doesNotWork = obsAction |> Observable.Create |> Observable.subscribe(fun time -> printfn "Time: %A" time)
答案 0 :(得分:2)
你遇到的问题是FP问题。
在,
static member Create(subscribe) =
Observable.Create(fun observer -> Action(subscribe observer))
subscribe
的类型为IObserver<_> -> unit -> unit
。
现在IObserver<_> -> unit -> unit
之间存在细微差别
和IObserver<_> -> Action
其中Action : unit -> unit
。区别在于前者是咖喱,而后者不是。
当观察者订阅时,subscribe observer
会返回一个方法,()
可以应用于unit
- 您的订阅方法将永远不会被调用,直到最后()
应用 - 直到它取消订阅才会被分离。
你可以通过强迫它不被咖喱来克服它:
let action() = ... | let action = (subscribe observer)
Action(action)
此外:
如果检查IL,则为Invoke
生成的FastFunc
的等效VB(函数引用在VB中更清晰)版本
static member Create(subscribe) =
Observable.Create(fun observer -> Action(subscribe observer))
是:
Friend Function Invoke(ByVal arg As IObserver(Of a)) As Action
Return New Action(AddressOf New Observable-Create-Static@27-1(Of a)(Me.subscribe, arg).Invoke)
End Function
和for:
static member Create(subscribe) =
Observable.Create(fun observer ->
let action = subscribe observer
Action(action))
是:
Friend Function Invoke(ByVal arg As IObserver(Of a)) As Action
Return New Action(AddressOf New Observable-Create-Static@28-1(Me.subscribe.Invoke(arg)).Invoke)
End Function
AddressOf New Closure(Me.subscribe, arg).Invoke
- &gt;在调用dispose操作之前,订阅函数不会被调用。
AddressOf New Closure(Me.subscribe.Invoke(arg)).Invoke
- &gt;实际调用了subscribe函数,并按预期返回结果操作。
我希望现在很清楚为什么第二种情况有效,而不是第一种情况。