.NET接收的优势超过传统比赛项目? [英] Advantages of .NET Rx over classic events?

查看:156
本文介绍了.NET接收的优势超过传统比赛项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

.NET 4.0 Beta 2的有<一个href="http://blogs.msdn.com/bclteam/archive/2009/10/21/what-s-new-in-the-bcl-in-net-4-beta-2-justin-van-patten.aspx">introduced在的IObservable 和的IObserver 接口。

有哪些优势比较经典的.NET事件?这是否解决同样的问题?

What are the advantages compared to classic .NET events? Doesn't this solve the same problem?

推荐答案

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

You can use IObservable as an event, replacing code that exposes events with properties of type IObservable, but that's not really the point.

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

There are two important things to understand about IObservable:

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

  1. It unifies two concepts that we didn't know how to unify before: asynchronous operations (which typically return a single value) and events (which typically go on forever).

这是组合的。不同于CLR事件,IAsyncResult的,或INotifyCollectionChanged它使我们能够建立特定的事件了一般事件和异步操作。

It is composable. Unlike CLR events, IAsyncResult, or INotifyCollectionChanged it allows us to build specific events out of general events and asynchronous operations.

下面是一个例子,我碰到了在工作中只是今天下午。

Here's an example I ran into at work just this afternoon.

在Silverlight中有一些效果,您可以适用于不能被应用到正常的图像控制。为了克服这些限制,当控件的内容发生变化,我可以为它的外观等进行更新,并采取它的屏幕截图。然后,我想隐藏它的视觉重新presentation,它与快照替换,并应用视觉效果的图像。现在,我可以申请图像效果控制(假设它不是交互式)。

In Silverlight there are some effects you can apply to an image control that cannot be applied to a normal control. To get around these limitations when a control's content is changed I can wait for its visual appearance to be updated and take a screenshot of it. Then I want to hide its visual representation, replace it with the snapshot, and apply the visual effects to the image. Now I can apply image effects to a control (assuming it's not interactive).

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

This program would be trivial but for the fact that it must be asynchronous. I must wait for two consecutive asynchronous operations to complete before I can apply effects to the image:

  1. 控件的内容更改
  2. 控件的外观进行更新

下面是我解决利用接收这个问题:

Here's how I'd solve this problem using 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);
   }
}

此例特别简单鉴于只有两个连续的操作顺序。即使在这种简单的例子,虽然我们可以看到,接收增加价值。如果没有它,我将不得不使用了状态变量,以确保事件按照一定的顺序点火。我也已经不得不写一些pretty的丑陋code,以明确地从LayoutUpdated事件分离。

This example is particularly simple given that there is only two consecutive operations to sequence. Even in this simple example though we can see that Rx adds value. Without it I would have had to have used state variables to ensure the events were firing in a certain order. I also would've had to write some pretty ugly code to explicity detach from the LayoutUpdated event.

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

When you're programming with Rx the trick is to think "What event do I wish my framework provided?" and then go create it. We're trained to think about events as simple, input-driven things ("mouseover", "mouseclick", "keyup", etc). However there's no reason events can't be very complex and specific to your app ("GoogleMsdnMashupStockDataArrived", "DragStarting", and "ImageContentChanged"). When you structure your programs this way (create exactly the event I need and then respond to it by changing state) you'll find that they have fewer state bugs, become more ordered, and are altogether more self-describing.

明白了吗? :-)

这篇关于.NET接收的优势超过传统比赛项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆