等待F#中的RX主题

时间:2016-01-14 00:10:23

标签: f# system.reactive

这与How do I await a response from an RX Subject without introducing a race condition?相同,但在F#中。

C#解决方案如下:

static async void Foo()
{
    var subject = new Subject<int>();
    var firstInt = subject.FirstAsync().PublishLast();
    firstInt.Connect();
    subject.OnNext(42);

    var x = await firstInt;
    Console.WriteLine("Done waiting: " + x);
}

我在F#中的尝试是这样的:

let foo () =
    async {
        use subject = new Subject<int>()
        let firstInt = subject.FirstAsync().PublishLast()
        firstInt.Connect() |> ignore
        subject.OnNext(42)

        let! x = firstInt
        printfn "Done waiting: %d" x
        return ()
    }

let x! = firstInt给出了编译错误This expression was expected to have type Async<'a> but here has type IConnectableObservable<int>,所以显然C#做了F#没有做的事情。

这里是否有一个C#隐式接口,我需要在F#中明确地做什么?如果是这样,我无法弄清楚它是什么。

1 个答案:

答案 0 :(得分:4)

在进一步挖掘之后,当你GetAwaiter()时,C#似乎会调用await。对于SubjectIObservableGetAwaiter会返回AsyncSubject,这在F#中不会立即生效,但ToTask中的System.Reactive.Threading.Tasks扩展方法{1}}使它变得有用。显然,您可以直接将ToTask应用于Subject(或IObservable)而无需GetAwaiter,因此我的问题可以通过更改{{1}来解决声明:

let! x ...

编辑:

有更好的方式

使用FSharpx.Async是完成同样事情的更好方法:

    let! x = firstInt.ToTask() |> Async.AwaitTask