是否有现成的群组活动解决方案?
说我有两个事件:A和B. 我希望在A和B被触发时执行方法M,它们不需要同时触发。
像: 小组赛事G同时发射,A和B都被解雇。我只需要在Group事件G中注册Method 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 表示事件触发, 0 它没有。
答案 0 :(得分: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, ...)
触发两个事件时会触发生成的observable。
修改
CombineLatest
生成具有最新结果的输出,而不重置其状态。因此,例如,如果A1被激发,那么B1被激发G1被产生(A1 + B1),但是如果B2被激发则G2产生(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扩展,但我找不到它。
答案 1 :(得分:3)
我认为Reactive Extensions可能与您正在寻找的最接近。它提供了将事件转换为可观察对象的助手,以及可用于组合这些可观察对象的linq样式语法。
答案 2 :(得分:1)
你可以自己写一堂课。这是一个(非常)微不足道的实现:
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; }
这只是一个概念性实现,您可能希望将事件委托作为通用,将其扩展为n个事件而不是仅仅两个,(可能)处理事件触发之间的超时,思考如何这个课程将被扩展(如果有的话),等等。
@spender对Rx的建议是值得的(+1),但该库适用于异步事件,并且学习曲线有些陡峭。如果您只想要已知事件的简单分组,或者相同类型的事件而不是完全通用的事件,则可能会有些过分。