回答
您可以使用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编程时,诀窍是想“我希望我的框架提供什么事件?”然后去创建它。我们训练将事件视为简单的输入驱动事物(“鼠标悬停”,“鼠标点击”,“键盘”等)。然而,没有理由说明事件不会非常复杂且特定于您的应用(“GoogleMsdnMashupStockDataArrived”,“DragStarting”和“ImageContentChanged”)。当你用这种方式构建你的程序时(创建我需要的事件,然后通过改变状态来响应它),你会发现它们有更少的状态错误,变得更有序,并且更加自我描述。
Got it? :-)
它只是基于事件的编程模型的扩展。你创建了一些实现IObserver的东西,基本上你会说“这是我在集合中的某些东西发生变化时想要发生的事情”。这样,这只是我们在事件中所做的一切标准化工作。
与IEnumerable模式相比,它们正在推动它的发展。 IEnumerable是“拉”,而IObservable是“推”。
我看到的直接事件的唯一优点是它是一个标准化的接口。虽然(和INotifyCollectionChanged)在这里我看到了与ObservableCollection的重叠。也许他们试图在.NET中采用PERL座右铭:“有多种方法可以实现它”。
我不知道的优点,但我看到经典的.NET事件有以下区别:
错误通知
经典事件将需要为这个单独的事件,或EventArgs
类需要检查的Error
属性。
结束通知的通知
经典事件将需要为这个或与需要检查一个Final
财产独立事件的EventArgs
类。
您一定要观看Rx Workshop: Observables versus Events视频和 填写所附的挑战
- 1. MySQLi优于MySQL的优势
- 2. Spring Dot Net Remoting的优势
- 3. /proc文件系统的优势
- 4. 关于SaaS优势
- 5. pathmunge优于grep的优势是什么?
- 6. ASP.net CORE优于Asp.net的主要优势
- 7. Kafka优于RabbitMQ的优势是什么?
- 8. .NET 3.5与.NET 3.0的用户优势
- 9. 优势
- 10. 优势
- 11. 优势
- 12. 优势
- 13. 优势Activator.CreateInstance的
- 14. BTREE的优势?
- 15. 统计员超过集合的优势
- 16. JavaScript:停止事件传播是否有任何性能优势?
- 17. SO的硬件优势
- 18. 与.NET Cache系统相比,Memcached有什么优势?
- 19. 优势表
- 20. 优势5400 AE_INTERNAL_ERROR
- 21. MVC优势
- 22. 优势在Perl
- 23. 优势在asp.Net
- 24. 优势控制
- 25. 优势OOP
- 26. 对于简单功能静态优于静态优势
- 27. 优势B树+的
- 28. Jquery Templates的优势
- 29. nuSOAP WebService的优势?
- 30. 优势VS ReSharper的
斯科特接下来的问题是,将框架的样子,如果的IObservable和IObserver在框架的第1版实施了什么。 错误处理和事件编程本来就是可组合的。 处理异步和同步事件的常用方法。 并行扩展将使用IObservable类型。 但最重要的是,这将从一开始就全部组合在一起,如果现在不是几乎不可能的话,这将大大简化许多难以处理的项目。 (单元测试异步UI是我头脑中想到的一个) – DouglasH 2009-10-02 18:41:36
@Doughlas,但我们不能重写历史,所以这个问题不是“theOldWay或Rx”,而是“theOldWay OR(theOldWay和Rx )“ – 2010-02-24 11:00:49