C#中的IObserver和IObservable用于观察者与代理,事件

我所要做的就是实现观察者模式。

所以,我提出了这个解决方案:

我们有一个PoliceHeadQuarters,其主要工作是向所有订阅者发送通知。 考虑到DSP,Inspector和SubInspector类订阅了PoliceHeadQuarters。

使用事件和代表我写道

public class HeadQuarters { public delegate void NewDelegate(object sender, EventArgs e); public event EventHandler NewEvent; public void RaiseANotification() { var handler = this.NewEvent; if (handler != null) { handler(this, new EventArgs()); } } } public class SubInspector { public void Listen(object sender, EventArgs e) { MessageBox.Show(string.Format("Event Notification received by sender = {0} with eventArguments = {1}", sender, e.ToString())); } } public class Inspector { public void Listen(object sender, EventArgs e) { MessageBox.Show(string.Format("Event Notification received by sender = {0} with eventArguments = {1}", sender, e.ToString())); } } 

这就是我调用它的方式

  var headQuarters = new HeadQuarters(); var SubInspector = new SubInspector(); var Inspector = new Inspector(); headQuarters.NewEvent += Inspector.Listen; headQuarters.NewEvent += SubInspector.Listen; headQuarters.RaiseANotification(); 

因此,无论何时调用函数RaiseANotification(),Inspector和SubInspector类都会收到通知。

似乎DotNet Framework 4,4.5支持一种称为IObserver和IObservable的新方法。

任何人都可以使用IObservable和IObserver模式为我提供一个超级简单的例子用于上述场景吗? 我用Google搜索,发现互联网上的可用示例过于臃肿且难以理解。

我的想法:(可能我认为这是错的)

  class DSP : IObserver //since it observes the headquarters ? class PoliceHeadQuarters: IObservable // since here's where we send the notifications ? 

提前致谢。

编辑:有人还说,对于IObservable @ IObservable vs Plain Events ,MSDN文档也是不正确的, 或者我为什么要使用IObservable? 。

以下是适合您的框架的MSDN示例的修改:

  public struct Message { string text; public Message(string newText) { this.text = newText; } public string Text { get { return this.text; } } } public class Headquarters : IObservable { public Headquarters() { observers = new List>(); } private List> observers; public IDisposable Subscribe(IObserver observer) { if (!observers.Contains(observer)) observers.Add(observer); return new Unsubscriber(observers, observer); } private class Unsubscriber : IDisposable { private List> _observers; private IObserver _observer; public Unsubscriber(List> observers, IObserver observer) { this._observers = observers; this._observer = observer; } public void Dispose() { if (_observer != null && _observers.Contains(_observer)) _observers.Remove(_observer); } } public void SendMessage(Nullable loc) { foreach (var observer in observers) { if (!loc.HasValue) observer.OnError(new MessageUnknownException()); else observer.OnNext(loc.Value); } } public void EndTransmission() { foreach (var observer in observers.ToArray()) if (observers.Contains(observer)) observer.OnCompleted(); observers.Clear(); } } public class MessageUnknownException : Exception { internal MessageUnknownException() { } } public class Inspector : IObserver { private IDisposable unsubscriber; private string instName; public Inspector(string name) { this.instName = name; } public string Name { get { return this.instName; } } public virtual void Subscribe(IObservable provider) { if (provider != null) unsubscriber = provider.Subscribe(this); } public virtual void OnCompleted() { Console.WriteLine("The headquarters has completed transmitting data to {0}.", this.Name); this.Unsubscribe(); } public virtual void OnError(Exception e) { Console.WriteLine("{0}: Cannot get message from headquarters.", this.Name); } public virtual void OnNext(Message value) { Console.WriteLine("{1}: Message I got from headquarters: {0}", value.Text, this.Name); } public virtual void Unsubscribe() { unsubscriber.Dispose(); } } public class Program { public static void Main(string[] args) { Inspector inspector1 = new Inspector("Greg Lestrade"); Inspector inspector2 = new Inspector("Sherlock Holmes"); Headquarters headquarters = new Headquarters(); inspector1.Subscribe(headquarters); inspector2.Subscribe(headquarters); headquarters.SendMessage(new Message("Catch Moriarty!")); headquarters.EndTransmission(); Console.ReadKey(); } } 

另一个建议 – 您可能想要考虑使用IObservable为任何代码利用反应式扩展库。 nuget包是Rx-Main,它的主页在这里: http : //msdn.microsoft.com/en-us/data/gg577609.aspx

这将为您节省大量的样板代码。 这是一个非常简单的例子:

 var hq = new Subject(); var inspectorSubscription = hq.Subscribe( m => Console.WriteLine("Inspector received: " + m)); var subInspectorSubscription = hq.Subscribe( m => Console.WriteLine("Sub Inspector received: " + m)); hq.OnNext("Catch Moriarty!"); 

它将输出:

 Inspector received: Catch Moriarty! Sub Inspector received: Catch Moriarty! 

Reactive Extensions是一个很大的主题,也是一个非常强大的库 – 值得研究。 我从上面的链接推荐动手实验室。

您可能希望在Inspector中嵌入这些订阅,SubInspector immplementatinos以更密切地反映您的代码。 但希望这能让您深入了解使用Rx可以做些什么。