.NET Rx优于传统事件的优点?

.NET 4.0 beta 2具有introducedIObservableIObserver接口。

与传统的.NET事件相比有什么优点?这不是解决同样的问题吗?

您可以使用IObservable作为事件,替换使用IObservable类型的属性公开事件的代码,但这不是真正的要点。

有两个重要的事情要了解IObservable:

>它统一了我们不知道如何统一的两个概念:异步操作(通常返回单个值)和事件(通常永远)。
>它是可组合的。与CLR事件,IAsyncResult或INotifyCollectionChanged不同,它允许我们从一般事件和异步操作中构建特定事件。

这是我今天下午在工作中遇到的一个例子。

在Silverlight中,有一些效果可以应用于不能应用于正常控件的图像控件。为了克服这些限制,当控件的内容更改时,我可以等待其可视外观更新并截取它的屏幕截图。然后,我想隐藏其视觉表示,将其替换为快照,并将视觉效果应用于图像。现在我可以应用图像效果到控件(假设它不是交互式)。

这个程序是微不足道的,但事实上它必须是异步的。我必须等待两个连续的异步操作完成,然后我才能对图像应用效果:

>控件的内容已更改
>控件的视觉外观被更新

这里是我如何解决这个问题使用Rx:

// A content control is a control that displays content.  That content can be
// anything at all like a string or another control.  Every content control contains
// another control: a ContentPresenter.  The ContentPresenter's job is to generate
// a visual representation of the Content property. For example, if the Content property
// of the ContentControl is a string, the ContentPresenter creates a TextBlock and inserts
// the string into it.  On the other hand if the Content property is another control the 
// ContentPresenter just inserts it into the visual tree directly.
public class MyContentControl : ContentControl
{
   // A subject implements both IObservable and IObserver.  When IObserver methods
   // are called, it forwards those calls to all of its listeners.
   // As a result it has roughly the same semantics as an event that we can "raise."
   private Subject<object> contentChanged = new Subject<object>();

   // This is a reference to the ContentPresenter in the ContentControl's template
   private ContentPresenter contentPresenter; 

   // This is a reference to the Image control within ContentControl's template.  It is displayed on top of the ContentPresenter and has a cool blur effect applied to it.
   private Image contentImageControl; 

   public MyContentControl()
   {
      // Using Rx we can create specific events from general events.
      // In this case I want to create a specific event ("contentImageChanged") which
      // gives me exactly the data I need to respond and update the UI.
      var contentImageChanged = 
         // get the content from the content changed event
         from content in contentChanged
         where content != null
         // Wait for the ContentPresenter's visual representation to update.
         // ContentPresenter is data bound to the Content property, so it will
         // update momentarily.
         from _ in contentPresenter.GetLayoutUpdated().Take(1)
         select new WritableBitmap(contentPresenter, new TranslateTransform());

      contentImageChanged.Subscribe(
         contentImage => 
         {
            // Hide the content presenter now that we've taken a screen shot              
            contentPresenter.Visibility = Visibility.Collapsed; 

            // Set the image source of the image control to the snapshot
            contentImageControl.ImageSource = contentImage;
         });
   }

   // This method is invoked when the Content property is changed.
   protected override OnContentChanged(object oldContent, object newContent)
   {
      // show the content presenter before taking screenshot
      contentPresenter.Visibility = Visibility.Visible;  

      // raise the content changed "event"
      contentChanged.OnNext(newContent);   

      base.OnContentChanged(oldContent, newContent);
   }
}

假定只有两个连续的操作要进行排序,这个例子特别简单。即使在这个简单的例子中,我们可以看到Rx增加了价值。没有它,我不得不使用状态变量来确保事件以一定的顺序触发。我也不得不写一些相当丑陋的代码来Explicit从LayoutUpdated事件分离。

当你使用Rx编程时,诀窍是想想“我希望我的框架提供什么事件?然后去创建它。我们经过培训,认为事件是简单的,输入驱动的东西(“mouseover”,“mouseclick”,“keyup”等)。但是没有理由事件不能是非常复杂和特定于你的应用程序(“GoogleMsdnMashupStockDataArrived”,“DragStarting”和“ImageContentChanged”)。当你以这种方式构建你的程序(创建我需要的事件,然后通过改变状态来响应它),你会发现他们有更少的状态错误,变得更有序,并且完全更自我描述。

得到它了? 🙂

http://stackoverflow.com/questions/1212536/advantages-of-net-rx-over-classic-events

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:.NET Rx优于传统事件的优点?