【问题标题】:Is it possible to replace traditional event handling in C# with the new Reactive framework?是否可以用新的 Reactive 框架替换 C# 中的传统事件处理?
【发布时间】:2009-08-23 18:43:23
【问题描述】:

到目前为止我看到的关于 System.Reactive.dll 的所有示例都涉及事件、EventArgs 和 EventHandlers,我想知道是否有人可以向我展示一个在没有这些的情况下处理事件通知的示例。

例如,在 Microsoft 的 XNA 框架中,您有一个名为 Mouse.GetState() 的静态方法,它将返回当前的 MouseState(使用 mouseState.LeftButton == ButtonState.Pressed 您可以查看左键是否被按下,例如)。所以一开始就没有 EventArgs、Events 等,我认为这可以作为实现事件通知的一个例子,而不需要引入事件的概念。

System.Reactive 能帮上忙吗?任何人都可以使用 System.Reactive 将其包装到一个示例中吗?

【问题讨论】:

标签: c# event-handling xna system.reactive


【解决方案1】:

来自article 的引用,我觉得很有帮助:

在 C# 中,程序员使用 反应式编程,每当他 指定一个回调 异步操作或处理程序 对于一个事件。当异步 操作完成或处理时 事件发生,方法得到 调用并执行作为对 事件。

Mouse.GetState() 是一种获取鼠标当前状态的方法。如果您试图持续处理(反应)鼠标状态的变化,反应式编程会很有用。

例如,您可以创建一个包装器,它不断地轮询鼠标状态,然后通知其观察者(本质上是回到这里发布事件)。然后,您可以编写代码来处理(响应)这些更新。

【讨论】:

    【解决方案2】:

    轮询鼠标或键盘状态在您可以直接访问作为应用程序心跳的更新方法的游戏中起作用。 update 方法是您的事件,它被调用并传递给许多对象,与 MouseDown 没有太大区别。所以即使在这里你也确实依赖于观察者模式。

    【讨论】:

    • 我知道,但这是关于 System.Reactive.dll 及其 IObservable、IObserver 接口的具体问题
    【解决方案3】:

    您可以从现有事件创建 Observable。您可以为此目的使用 Observable.FromEvent。您可以像这样编写 GetMouseDown 事件包装器,作为 UI 元素的扩展方法。

     public static IObservable<Event<MouseButtonEventArgs>> 
                                          GetMouseDown (this UIElement el)
        {                        
            var allevents = Observable.FromEvent<MouseButtonEventHandler, MouseButtonEventArgs>
                (   h => new MouseButtonEventHandler(h), 
                    h => el.MouseDown += h, 
                    h=> el.MouseDown -= h
                 );
    
            return allevents;            
        }   
    

    然后,您可以以完全声明的方式“处理”您的事件。喜欢

    //create an observable declaratively
    var mouseDowns=button.GetMouseDown(); 
    //subcribe and do what ever you need
    mouseDowns.Subscribe(arg=> MessageBox.Show(arg.ClickCount.ToString()) ); 
    

    这里是如何使用初始位置和当前位置创建一个“拖动”可观察对象。

      //Get the initial position and dragged points using LINQ to Events
                var mouseDragPoints = from md in e.GetMouseDown()
                                      let startpos=md.EventArgs.GetPosition(e)
                                      from mm in e.GetMouseMove().Until(e.GetMouseUp())
                                      select new
                                      {
                                          StartPos = startpos,
                                          CurrentPos = mm.EventArgs.GetPosition(e),
                                      };
    
    
     //And subscribe here to mouseDragPoints
    

    阅读这篇文章LINQ to Events - More on .NET Reactive Extensions 并玩弄源代码。

    【讨论】:

    猜你喜欢
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 2011-10-13
    • 2017-11-04
    • 2019-06-19
    相关资源
    最近更新 更多