.NET 4.0的β2已经介绍的的IObservable和IObserver接口。
什么是比较经典的.NET事件优势? 这难道不是解决同样的问题?
.NET 4.0的β2已经介绍的的IObservable和IObserver接口。
什么是比较经典的.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增加价值。 没有它,我将不得不使用了状态变量,以确保事件按照一定的顺序进行射击。 我也一直有写一些非常丑陋的代码来显式地从LayoutUpdated事件分离。
当你使用的Rx编程技巧是认为“我希望有什么活动我的框架提供?” 然后去创造它。 我们正在训练的思考事件那么简单,输入驱动的东西(“鼠标悬停”,“鼠标点击”,“KEYUP”等)。 但是没有理由的事件不能很复杂,具体到您的应用程序(“GoogleMsdnMashupStockDataArrived”,“DragStarting”和“ImageContentChanged”)。 当你组织你的程序这样(创建正是我所需要的事件,然后通过改变国家应对它),你会发现他们有较少的状态错误,变得更有序,而且更完全自我描述。
得到它了? :-)
我不知道的优点,但我看到经典的.NET事件有以下区别:
错误通知
经典事件将需要为这个单独的事件,或EventArgs
与类Error
,需要进行检查属性。
结束通知的通知
经典事件将需要为这个或一个单独的事件的EventArgs
一类Final
需要被检查属性。
这只是一个扩展基于事件的编程模型。 你创造的东西,实现IObserver,基本上你说“这里就是我想的时候发生的东西在收集的变化”。 通过这种方式,它只是一个我们都被与事件做标准化。
他们正在推动它就像是一个大的挽回颜面与IEnumerable的模式进行比较。 IEnumerable的是“拉”,而的IObservable是“推”。
我看到过直的事件唯一的好处是,它是一个标准化的接口。 我看到一个大的重叠的ObservableCollection这里虽然(和INotifyCollectionChanged)。 也许他们正试图采用PERL座右铭与.NET:“不止一种方法去做一件事”。
你一定要观看的Rx研讨会:观测量与活动视频和填写所附的挑战