2

リストに 3 つの製品があるとします。特定のアクションを有効にするには、3 つすべてが特定のタイプである必要があります。商品の種類を知るために、サービスコールをして応答を待つ必要があります。

私がやりたいことは、3 つの応答すべてを待ち (何か問題が発生した場合に備えてタイムアウトを設定することもできます)、すべての情報が収集されたら、可能なアクションを有効にするかどうかを決定することです。

以前は、終了したイベントを追跡するためにいくつかのカウンターまたはリセット イベントを使用してこれを解決していましたが、Rx を使用してよりクリーンな方法で実行できるかどうかを確認したいと思います。

私はまだ Rx にあまり慣れていないので、ヒントやヒントを探しています。了解しました 使えます

Observable.FromEventPattern

私が待っているイベントのために。私はサブスクライブし、応答を待って処理します。複数のイベントを組み合わせる方法がよくわかりません。

4

1 に答える 1

4

The combinator you are looking for is CombineLatest

Say you've got a class like this:

public class Foo
{
    public delegate void FooEventHandler(object sender, EventArgs args);

    public event FooEventHandler FirstEvent = delegate {};    
    public event FooEventHandler SecondEvent = delegate {};    
    public event FooEventHandler ThirdEvent = delegate {};    

    public void DoIt()
    {
        FireOne();
        FireTwo();
        FireThree();
    }

    public void FireOne()
    {
        Console.WriteLine("Firing event 1...");
        Thread.Sleep(1000);
        FirstEvent(this, new EventArgs());
    }
    public void FireTwo()
    {
        Console.WriteLine("Firing event 2...");
        Thread.Sleep(1000);
        SecondEvent(this, new EventArgs());
    }
    public void FireThree()
    {
        Console.WriteLine("Firing event 3...");
        Thread.Sleep(1000);
        ThirdEvent(this, new EventArgs());
    }
}

First you'd want to "convert" those events to Observable:

var foo = new Foo();
var firstWatcher = Observable.FromEventPattern(foo, "FirstEvent");
var secondWatcher = Observable.FromEventPattern(foo, "SecondEvent");
var thirdWatcher = Observable.FromEventPattern(foo, "ThirdEvent");

Now you'll want the "Only fire when all these have fired" selector, which is CombineLatest:

var allDone = Observable.CombineLatest(firstWatcher, secondWatcher, thirdWatcher);

And to test it out:

using(allDone.Subscribe(_ => Console.WriteLine("Boop! You sunk my battleship!")))
{
    foo.DoIt();
}    

Alternative "test harness":

var foo = new Foo();
var firstWatcher = Observable.FromEventPattern(foo, "FirstEvent");
var secondWatcher = Observable.FromEventPattern(foo, "SecondEvent");
var thirdWatcher = Observable.FromEventPattern(foo, "ThirdEvent");

var allDone = Observable.CombineLatest(firstWatcher, secondWatcher, thirdWatcher);

// keep a handle on the subscription            
IDisposable subscription = null;

// to prevent premature exiting...
var blocker = new ManualResetEvent(false);

// explicit subscribe
subscription = allDone.Subscribe(
    whoCares => 
    {
        Console.WriteLine("BOOM! We're done!");
        // always clean up after yourself
        if(subscription != null)
        {
            subscription.Dispose();
        }
        // it's ok, we can quit now
        blocker.Set();
    });

foo.DoIt();

// Wait until it's clear to go ahead...
blocker.WaitOne();
于 2013-01-16T17:36:45.430 に答える