- 浏览: 399526 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (309)
- xaml C# wpf (0)
- scala java inner clas (1)
- Tools UML Eclipse UML2 (1)
- Timer .NET Framework (1)
- perl (6)
- python function paramter (1)
- Python Docstring (1)
- Python how to compare types (1)
- Python (8)
- java (5)
- C# (76)
- C# WPF (0)
- p4 (0)
- WPF (46)
- .net (6)
- xaml (1)
- javascript (40)
- windows (10)
- scala (4)
- winform (1)
- c++ (48)
- tools (12)
- cmd (1)
- os (0)
- CI (0)
- shell (0)
- C (2)
- haskell (49)
- functional (1)
- tool (1)
- gnu (1)
- linux (1)
- kaskell (0)
- svn (0)
- wcf (3)
- android (1)
最新评论
Delegate offers some nice features of observable pattern, however, there are some limiation on the delgate implemented observable patterns.
Why not Delegate
For onething, there is no way to know when the subject no longer tick; the subject may become out of interest if it does not tick updates; But with the passive mode of delegate, you do not know that a subject is become inactive as the pattern itself is passive (there are some workaround , indeed by you provide another event to nofity that the subject is beome inactive);
For another, there is no way to descrimate against a valid udpate from error conditions, using some sentry value as the update event args could serve in some cases, but that is a botch/tinker/bumble/bungle rather than good solution, it is a smell design to intermingle the normal message channel with the error message channel;
for yet another, there is no way to know when/how to remove the IObserver from the notification list, a simple -= may unsusbscribe the event listener, but there would exist a huge amount of house keeping work that needs to be addresseed when an Observer go out of scope. Better, a Disposable is better in situation like this;
IObservable<T> and IObserver<T> pattern provides the cure;
It has provide the following.
- IObservable<T>.Subscribe(IObserver<T> observer): this notify the IObserver to add the observer to its notification list;
the return value of IDisposable, which satisify the the question of "how to remove teh IObserver from the notification list";
- IObserver<T>.OnComplete: This notifies that the provider has finished sending push-based notification
this has the functionality of telling the observers when the subject (provider) will/has become inactive. and on receiving the information, teh IObserver can use the IDispose method that it receives in the Subscribe step to unsubscibe itself from the notification and do the proper uninitialization.
- IObserver<T>.OnErro(Exception erorr): this satisfy the question of how to notify the client when some error condition has happens.
- IObserver<T>.OnNext(): this satisfy the basic requirement of the Provider notifies the clien when there is update coming.
Below shows the code an example IObservable<T> implementation, the T is of type Location, which represent some Location information.
namespace PushBasedNotificationTest { public struct Location { double lat, lon; public Location(double latitude, double longitude) { this.lat = latitude; this.lon = longitude; } public double Latitude { get { return this.lat; } } public double Longitude { get { return this.lon; } } } }
LocationTracker is our impl of IObservable<Location>, here it is:
namespace PushBasedNotificationTest { public class LocationTracker : IObservable<Location> { public LocationTracker() { // initialize the list of Observers to the Updates observers = new List<IObserver<Location>>(); } // you need a collection of Observers // on which you can send the notification private List<IObserver<Location>> observers; // Subscribe an observer (IObserver<T>) to the observer list // notice the return value of the Subscribe method, // which is of type IDisposable. // normally the Observer will store the return value // and call the Dispose method from the IDisposable interface // the common work done in the Disposable method is to remove itself from the // notification list; public IDisposable Subscribe(IObserver<Location> observer) { if (!observers.Contains(observer)) observers.Add(observer); return new Unsubscriber(observers, observer); } // the Unsubscriber will be returned to Observer // which on dispose, can remove itself from the // notification list, // so it makes sense to extends the Unsubscriber from the // interface IDisposable // // Another note about the IDisposable implementation is that // the IObservable interface can hide the implementation inside its body // client to IObservable should not be aware of the implementation of the // interface, thus have better decoupling private class Unsubscriber : IDisposable { public Unsubscriber(List<IObserver<Location>> observers, IObserver<Location> observer) { _observers = observers; _observer = observer; } private List<IObserver<Location>> _observers; private IObserver<Location> _observer; public void Dispose() { if (_observer != null && _observers.Contains(_observer)) _observers.Remove(_observer); } } // though I think it is better to call the method Update // as what it does it to notify the observers that has registered to // itself ; // the notification is done by send message to the // OnComplete // OnNext // OnError // method of the IObserver<T> interface // the IObserver<T> interface can decide what action to take on // receiving the message on different channels. // public void TrackLocation(Nullable<Location> loc) { foreach (var observer in observers) { if (!loc.HasValue) { observer.OnError(new LocationUnknownException()); } else { observer.OnNext(loc.Value); } } } // Or I think a better name could be // EndUpdate // because what it does it to signal the end of updates // from this very IObservable interface public void EndTransmission() { foreach (var observer in observers.ToArray()) { if (observers.Contains(observer)) observer.OnCompleted(); } // Is it necessary to do the // IList.Clear() call? // because the IObserver<T> method should have the necessary Dispose method to remove // the list... // However, I think as a defensive means, it is necessary observers.Clear(); } } }
and the LocationReporter is the Observer which implements the IObserver<Location> interface:
namespace PushBasedNotificationTest { public class LocationReporter : IObserver<Location> { // Remeber what we have said before, we subscribe the IObserver // and we get back a IDisposable // instance, the intance will helps us do the necessary disposition private IDisposable unsubscriber; private string instName; public LocationReporter(string name) { this.instName = name; } public string Name { get { return instName; } } // you can further encapsulate the IObservable<T> interface.Subscriber method // by the encapsulation, you can store the return value of the // IDisposable instance locally. // The benefit is that you can chain the Disposble method to destroy the // subscription once the ISubscriber is dead public virtual void Subscribe(IObservable<Location> provider) { if (provider != null) unsubscriber = provider.Subscribe(this); } public virtual void OnCompleted() { Console.WriteLine("The Location Tracker has completed transmitting data to {0}.", this.Name); } // The contract of the OnError is Exception E // where you can have subsclass of Exception passed in to indicate a specific kind of // error has happened public virtual void OnError(Exception e) { Console.WriteLine("{0}: The locatino cannot be determined.", this.Name); } public virtual void OnNext(Location value) { Console.WriteLine("{2}: the current location is {0}, {1}", value.Latitude, value.Longitude, this.Name); } // you can actually inherits the LocationReporter from IDisposable // where you can chain the Dispose method together public virtual void Unsubscribe() { unsubscriber.Dispose(); } } }
To communicate the eror condition, we will use the LocationException message as follow.
namespace PushBasedNotificationTest { // this is a custom type Exception that // you may pass to the OnError Notification channel of // IObserver<T> interface. public class LocationUnknownException : Exception { internal LocationUnknownException() { } } }
The last point, is the drive class that wires up the Observer and their Observables.
namespace PushBasedNotificationTest { class Program { static void Main(string[] args) { // Define a provider and two observers LocationTracker provider = new LocationTracker(); LocationReporter reporter1 = new LocationReporter("FixedGPS"); reporter1.Subscribe(provider); LocationReporter reporter2 = new LocationReporter("MobileGPS"); reporter2.Subscribe(provider); provider.TrackLocation(new Location(47.6456, -122.1312)); reporter1.Unsubscribe(); provider.TrackLocation(new Location(47.6677, -122.1199)); provider.TrackLocation(null); // trigger the error condition provider.EndTransmission(); } } }
发表评论
-
wpf - example to enhance ComboBox for AutoComplete
2014-09-19 15:56 1976first let’s see an example ... -
Investigate and troubleshoot possible memory leak issue of .NET application
2014-07-31 10:42 0Hi All, I would like to sh ... -
C# – CoerceValueCallback合并、替换元数据值
2013-08-05 21:59 1925Topic: C# – CoerceValueCallbac ... -
wpf – ListView交替背景色
2013-07-02 20:56 6551Wpf – Alternate background col ... -
C# - 简单介绍TaskScheduler
2013-06-29 17:18 12038标题: C# - 简单介绍TaskSchedulerTit ... -
c# - Get enum from enum attribute
2013-06-27 21:32 1244DescriptionAttribute gives the ... -
C# - PInvoke, gotchas on the RegisterClassEx and the CreateWindowEx
2013-06-24 13:49 2571I get an exception message li ... -
c# - Use PInvoke to create simple win32 Application
2013-06-24 11:59 10946In this post, .net platform h ... -
c# - Linq's Select method as the Map function
2013-06-19 18:47 1287If you comes from a functiona ... -
c# - Tips of Linq expression Any to determine if a collection is Empty
2013-06-19 18:29 938When you are @ the linq expres ... -
myth buster - typeof accepting array of types not acceptable
2013-06-19 17:17 813I have seen from some book whe ... -
windows - trying to create WIN32 application with PInvoke
2013-06-19 14:34 0While it is stupid to do such ... -
WPF - Setting foreground color of Entire window
2013-06-13 16:00 1918You might as well as I would s ... -
WPF - Enhanced TabControl - TabControlEx aka Prerendering TabControl
2013-06-13 13:12 5330As an opening word, let's che ... -
wpf - ControlTemplate and AddLogicChild/RemoveLogicalChild
2013-06-10 15:42 1185Recently I was trying to debug ... -
c# - P/Invoke, DllImport, Marshal Structures and Type conversions
2013-06-05 15:25 1712P/Invoke as in the following q ... -
c# - A study on the NativeWindow - encapsulate window handle and procedure
2013-06-05 14:40 6091NativeWindow gives you a way t ... -
WCF - Notify server when client connects
2013-06-03 18:19 1220It is sometimes very importan ... -
wcf - Debug to enable Server exception in Fault message
2013-06-03 15:47 1091WCF will be able to send back ... -
c# - determine if a type/object is serialzable
2013-05-30 16:35 867In WCF, primitives type are s ...
相关推荐
实现Double dabble或shift和add-3算法以将二进制数转换为二进制编码的十进制。 使用反向双星号将输出的二进制编码的十进制转换为二进制数。 寄存器编号,移位流程和执行速度应使用5个样本进行测试SHIFT AND ADD 3...
本教程将引导你了解如何创建并使用Chrome扩展程序,特别关注"chrome-extension-dabble"项目。 一、Chrome扩展程序基础 Chrome扩展程序由几个关键组件组成: 1. **manifest.json**:这是扩展程序的配置文件,它...
使用Dabble扩展程序,您可以从任何商店剪辑家具,将它们可视化在一起,并在一个应用程序中跟踪预算! 从任何商店剪辑家具和装饰,将它们一起可视化,并在一个应用程序中跟踪您的预算! 家具购物就像是互联网上的一个...
“4-wheel-robot-made-with-arduino-controlled-using-dabble-4650f7.pdf”很可能是一份项目指南或教程文档,详细介绍了组装4轮机器人和设置Dabble控制的步骤。文档可能包括材料清单、电路图、代码解释和故障排除...
"smartphone-controlled-pc-game-using-dabble-app-607e65.pdf"很可能包含了项目指南、步骤说明或原理图。这份文档会详细解释如何配置Dabble App,如何编写Arduino代码,以及如何在PC上设置游戏控制器接收和解析...
【Dabble字体详解】 Dabble是一款独特而富有创意的字体,它以其独特的设计风格和广泛的适用性在字体设计领域中脱颖而出。"Dabble"这个名字本身就带有涂鸦、玩乐的意味,暗示了这款字体轻松、随性的设计理念。设计师...
在“dabble-in-java:Java书中的小项目”中,我们探索了由Tony Gaddis编著的《从Java入门,早期对象,第三版》一书中的一些实践项目。这个项目集合旨在帮助读者深入理解Java编程语言的核心概念和实战技巧。通过参与...
ejs通过提供简单的语法,如`<% %>`和`<%= %>`, 让开发者能够轻松地处理数据并将其呈现到页面上。在这个项目中,ejs可能被用来渲染3D模型的预览图或者与用户交互的界面,以便用户可以自定义3D模型的视图和转换设置。 ...
')->upper()->trim(); ``` 这行代码将创建一个字符串对象,然后将其转换为大写并去除两端的空白字符。 4. **类型安全**:Stringy保证了其内部始终处理字符串类型,避免了PHP中字符串与其他类型混合操作可能导致的...
"Z Dabble Down" 是一款独特的字体设计,它在IT行业中属于字体艺术的范畴,尤其适用于创意设计、图形用户界面(GUI)以及视觉传达等领域。这款字体以其独特的风格和个性吸引了许多设计师的关注。 首先,我们要了解...
##Parametric Double Dabble Binary to BCD Converter## ##Ameer M. Abdelhadi ( )## ###Parametric Binary to BCD Converter 使用 Double Dabble / Shift 和 Add 3 算法### 平台: DE2-115 Cyclone IV 开发板 ...
"WordPress主题:Dabble v1.5创意代理和投资组合主题2022年最新版 WordPress主题/WordPress插件/html网站模板/iOS app源码/安卓app源码 每天更新上传!" ---------- 每天更新发布最新WordPress主题、HTML主题、...
Dabble Me会在您选择的时间和日期向您发送电子邮件-您只需回复电子邮件即可发布条目。 该应用程序位于。 如果您曾经使用过则这是一个很好的替代品。 此应用程序利用以下第三者服务: 托管DNS +免费SSL支持(基本...
6. `babble` - 胡言乱语,`gabble` - 口齿不清,`dabble` - 涉足,`gobble` - 狼吞虎咽,`nibble` - 小口轻咽。口诀利用谐音和故事将这些动词联系起来,比如“abble 好象 able,baby 胡言乱语”。 7. `tumble` - ...
最后,表达对未来学习和发展的期望,例如:"If I have the opportunity to study in abc University, I’ll dabble in as much as document about the specialty as possible." 这展示了你积极进取的态度和明确的...
轻松投用Vimeo视频(使用vidcast - https://vidcast.dabble.me)到您的Chromecast :trade_mark:/ Android电视设备。 扩展将CAST选项添加到Vimeo视频的上下文菜单(右键单击)。 您必须安装Google Calt Extension。 ...
轻松地将Vimeo视频(使用VidCast-https://vidcast.dabble.me)投射到您的Chromecast:trade_mark:/ Android TV设备上。 该扩展程序在Vimeo视频的上下文菜单(右键单击)中添加了投射选项。 您必须安装Google Cast扩展...
该项目将向您展示如何制作DIY LED...你需要一个亚克力板,一个支架,一个原型板,如Arduino Nano,一个装有Dabble的智能手机,然后就可以开始你的DIY! 您可以从Google Play 下载Dabble 。 点亮3 ... 2 ... 1 ...现在!
该项目将向您展示如何使用智能手机的相机功能制作循迹机器人。 硬件组件: evive入门套件× 1 ...现在,它的另一个任务是做到循迹,这次用的是智能手机的相机和Dabble,一个智能移动应用程序,以帮助他们协调能力。