2

毎秒5秒間何かを試し、すべてがfalseの場合はfalseを返し、最初にtrueの場合はtrueを返したいと思います。必須では、次のようになります。

bool TryFiveTimes()
{
    for (int i = 0; i < 5; i++)
    {
        if (Fn())
            return true;
        System.Threading.Thread.Sleep(1000);
    }
    return false;
}

Rxを使用してこれを実行したいのですが、きちんとした方法を考えることができません。私の現在の試みは次のとおりです。

bool TryFiveTimes()
{
    return Observable.Interval(TimeSpan.FromSeconds(1))
        .Take(5)
        .Select(_ => Fn())
        .Scan(false, (curr, prev) => curr || prev)
        .Last();
}

Fn()これにより正しい結果が得られますが、終了前にtrueが返された場合、早期に戻ることはありません。

4

2 に答える 2

3

実装には.First()、代わりにメソッドを使用してください.Last()

    static bool TryFiveTimes()
    {
        return Observable.Interval(TimeSpan.FromSeconds(1))
            .Take(5)
            .Select(_ => Fn())
            .Scan(false, (curr, prev) => curr || prev)
            .FirstOrDefault(v => v);
    }

    static int counters = 0;
    static bool Fn()
    {
        counters++;
        Console.WriteLine(counters);
        return counters > 2;
    }

[編集]:Fnメソッドが最初に戻る前にのみ実行されることを証明するコードを追加しましたTrue

また、ここでは実際には必要ありませんScan()。短いバージョンは次のとおりです。

    return Observable
        .Interval(TimeSpan.FromSeconds(1))
        .Take(5)
        .Select(_ => Fn())
        .FirstOrDefault(v => v);
于 2013-01-11T07:36:49.903 に答える
2

次のように使用Concatしてみてください。Return

bool TryFiveTimes()
{
    return Observable
        .Interval(TimeSpan.FromSeconds(1))
        .Take(5)
        .Select(_ => Fn())
        .Where(x => x)
        .Concat(Observable.Return(false))
        .First();
}
于 2013-01-11T10:37:25.477 に答える