.NET Rx的优势,相比于传统的事件?(Advantages of .NET Rx over cl

2019-07-31 04:54发布

.NET 4.0的β2已经介绍的的IObservable和IObserver接口。

什么是比较经典的.NET事件优势? 这难道不是解决同样的问题?

Answer 1:

您可以使用的IObservable作为一个事件,替换暴露类型的IObservable的性质事件的代码,但是这不是真正的点。

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

  1. 它统一了两个概念,我们不知道如何前统一 :异步操作(通常返回一个值)和事件(通常永远持续下去)。

  2. 这是组合的 。 不同于CLR事件,IAsyncResult的,或INotifyCollectionChanged它使我们能够打造出一般事件和异步操作的具体事件。

下面是我遇到的工作就在今天下午的例子。

在Silverlight中有您可以申请不能被应用到正常的图像控制有一定的影响。 为了避开这些限制在控件的内容发生变化,我可以等待它的外观进行更新,并采取它的屏幕截图。 然后我想隐藏其可视化表示,与快照替换它,并应用视觉效果的图像。 现在,我可以申请图像效果控制(假设它不是互动)。

这个方案将是微不足道的,但一个事实,即它必须是异步的。 我必须等待两个连续的异步操作完成之前,我可以应用效果的图像:

  1. 控制的内容被改变
  2. 该控件的外观进行更新

以下是我想解决使用的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增加价值。 没有它,我将不得不使用了状态变量,以确保事件按照一定的顺序进行射击。 我也一直有写一些非常丑陋的代码来显式地从LayoutUpdated事件分离。

当你使用的Rx编程技巧是认为“我希望有什么活动我的框架提供?” 然后去创造它。 我们正在训练的思考事件那么简单,输入驱动的东西(“鼠标悬停”,“鼠标点击”,“KEYUP”等)。 但是没有理由的事件不能很复杂,具体到您的应用程序(“GoogleMsdnMashupStockDataArrived”,“DragStarting”和“ImageContentChanged”)。 当你组织你的程序这样(创建正是我所需要的事件,然后通过改变国家应对它),你会发现他们有较少的状态错误,变得更有序,而且更完全自我描述。

得到它了? :-)



Answer 2:

我不知道的优点,但我看到经典的.NET事件有以下区别:

错误通知

经典事件将需要为这个单独的事件,或EventArgs与类Error ,需要进行检查属性。

结束通知的通知

经典事件将需要为这个或一个单独的事件的EventArgs一类Final需要被检查属性。



Answer 3:

这只是一个扩展基于事件的编程模型。 你创造的东西,实现IObserver,基本上你说“这里就是我想的时候发生的东西在收集的变化”。 通过这种方式,它只是一个我们都被与事件做标准化。

他们正在推动它就像是一个大的挽回颜面与IEnumerable的模式进行比较。 IEnumerable的是“拉”,而的IObservable是“推”。

我看到过直的事件唯一的好处是,它是一个标准化的接口。 我看到一个大的重叠的ObservableCollection这里虽然(和INotifyCollectionChanged)。 也许他们正试图采用PERL座右铭与.NET:“不止一种方法去做一件事”。



Answer 4:

你一定要观看的Rx研讨会:观测量与活动视频和填写所附的挑战



文章来源: Advantages of .NET Rx over classic events?