Event Grouping in C #

Are there any ready-to-use solutions for group events?

Let's say I have two events: A and B. I want method M to execute when A and B were fired, they do not need to run exactly at the same time.

Something like: Group event G fires after both shots A and B. I need to register method M only with group event G.

A can fire more than once, G will burn only after B has fired. Similar.

I am looking for a library that has these events.

Edit: Example

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

F means the event is triggered; 0 is not.

+6
source share
3 answers

You can use Reactive Extensions .

Take a look at the Observable.FromEvent (or Observable.FromEventPattern) method to convert a standard .NET event to an observable, and then you can group the results using Observable.CombineLatest .

Here is the pseudo code:

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

The generated observable is triggered when both events are triggered.

EDIT

CombineLatest displays the result with the latest results without resetting its state. So, for example, if A1 is started, then B1 is started. G1 is produced from (A1 + B1), but if B2 is fired, G2 is made from (A1 + B2) and so on ...

To accurately represent the expected results, you can write something like:

  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"); //} 

Basically I check if the latest results are different from the current result. Perhaps for your case there is a native RX extension, but I can not find it.

+7
source

I think Reactive Extensions is probably closest to what you are looking for. It provides helpers with the ability to turn events into observables and linq-style syntax that you can use to compose these observables.

+3
source

You can write such a class yourself. Here's a (very) trivial implementation:

  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;
 }

This is just a conceptual implementation, you probably want the event delegate to be common, extend it to n events, not two, (maybe) deal with timeouts between events, think about how this class (if in general) etc.

The @spender Rx proposal costs (+1), but the library is oriented to asynchronous events and has a slightly steep learning curve. This might be redundant if you just want simple groupings of known events or events of the same type, rather than something in common.

0
source

Source: https://habr.com/ru/post/945526/


All Articles