2013-05-21 9 views
6

イベントをグループ化するためのソリューションはありますか?C#のグループ化イベント

AとBの2つのイベントがあるとします。 AとBが起動されたときにメソッドMを実行したい場合は、同時に起動する必要はありません。

何かのように: グループイベントGは、AとBの両方が発生した後に起動します。グループイベントGでのみメソッドMを登録する必要があります。

Aは複数回起動できますが、GはBが起動した後でのみ起動できます。同じように。

私はこれらのイベントを持っている図書館を探しています。

編集:例

Events: 
    A | B | G 
1 F 0 0 
2 0 F F 
3 0 F 0 
4 0 F 0 
5 0 F 0 
6 F 0 F 
7 F 0 0 
8 0 F F 
9 0 0 0 
10 F F F 

Fはそうでないイベントが発生し、 を意味します。

+4

a、a、a、b、bが発砲した場合、この場合何回gを発射すべきですか? – vittore

+0

または、あなたのコードでAとBが特定のインスタンスに対して1回だけ起動することを保証していますか?もっと詳細が本当に助けになるでしょう。 – Renan

答えて

7

Reactive Extensionsを使用できます。

Observable.FromEvent(またはObservable.FromEventPattern)メソッドを参照して、標準.NETイベントをobservableに変換してから、Observable.CombineLatestを使用して結果をグループ化できます。ここ

は擬似コードである:

var observableA = Observable.FromEvent(yourEventA); 
var observableB = Observable.FromEvent(yourEventB); 

var observableG = observableA.CombineLatest(observableB, ...) 

両方のイベントがトリガされたときに発生する観察がトリガされます。

EDIT

CombineLatestは、その状態をリセットすることなく、最新の結果と出力を生成します。例えばA1が発射され、B1が発射された場合、G1は(A1 + B1)で生成されますが、B2が発射されると(A1 + B2)などで生成されます...

正確に期待される結果は次のように書くことができます:

private void SetupEvents() 
    { 
     var observableA = Observable.FromEventPattern((e) => btA.Click += e, (e) => btA.Click -= e); 
     var observableB = Observable.FromEventPattern((e) => btB.Click += e, (e) => btB.Click -= e); 

     EventPattern<object> lastA = null; 
     EventPattern<object> lastB = null; 
     var observableG = observableA.CombineLatest(observableB, (rA, rB) => 
     { 
      if (lastA == rA || lastB == rB) 
       return null; 

      lastA = rA; 
      lastB = rB; 
      return new Tuple<EventPattern<object>, EventPattern<object>>(rA, rB); 
     }).Where(p => p != null); 

     observableG.Subscribe(r => Trace.WriteLine("A + B")); 

     // or use ToEvent to generate another standard .NET event 
     //observableG.ToEvent().OnNext += GEvent; 
    } 

    //void GEvent(System.Reactive.EventPattern<object> obj) 
    //{ 
    // Trace.WriteLine("A + B"); 
    //} 

最新の結果が現在の結果と異なるかどうかを確認します。 あなたのケースにネイティブRX拡張機能があるかもしれませんが、見つけられません。

3

Reactive Extensionsはおそらくあなたが探しているものに近いと思います。イベントをオブザーバブルに変換するヘルパと、それらのオブザーバを合成するためのlinq型のシンタックスを提供します。

0

あなたはこのようなクラスを自分で書くことができます。ここでは(非常に)些細な実装です:

 
public class TwoEventGroup 
{ 
    private bool _eventAFired; 
    private bool _eventBFired; 

    public void EventAHandler() 
    { 
     _eventAFired = true; 
     TestAndFire(); 
    } 

    public void EventBHandler() 
    { 
     _eventBFired = true; 
     TestAndFire(); 
    } 

    private void TestAndFire() 
    { 
     if (_eventAFired && _eventBFired) 
     { 
     _eventAFired = false; 
     _eventBFired = false; 
     if (GroupEvent != null) 
      GroupEvent(); 
     } 
    } 

    public event Action GroupEvent; 
} 

これは単に概念的な実装である、あなたはおそらくジェネリックとしてイベントデリゲートを持つようにしたいと思い、代わりにちょうど2つのn個のイベントにそれを拡張、(多分)契約イベント発砲の時間切れ、このクラスがどのように拡張されるかについて考える(もしあれば)など。

@spender Rxの提案は価値がありますが(+1)、ライブラリは非同期イベントに対応しており、幾分急な学習曲線。既知のイベントを単純にグループ化したり、同じタイプのイベントをグループ化したり、まったく一般的なイベントをグループ化したりしたくない場合は、残念です。

関連する問題