使用RX构建传感器监控系统 [英] Building a Sensor Monitoring System using RX
问题描述
请参见在RX中合并多个自定义可观察对象作为背景.
我的情况是我有许多任意传感器(硬件).我已经编写了一些可插入模块,这些模块可以连接到C#中的这些传感器.当前,它们每个都使用线程在计时器上运行获取例程.更大的目标是,一旦我了解如何将轮询改为RX!
My scenario is that I have a number of arbitrary sensors (hardware). I have written some pluggable modules that can connect to these sensors in C#. They currently each use a thread to run an acquisition routine on a timer. The larger goal is to change polling to RX as well once I understand how!
有一个需要对传感器进行分组监视的想法,所以我认为应该有一个聚合的主题,其中监视器可以订阅来自特定传感器组(温度,信号强度等)的更新,并可能对传感器进行更改.系统的行为基于传感器的读数.
There is a requirement to monitor these sensors in groups so I was thinking there would be an aggregated topic where a monitor could subscribe to for updates from a particular group of sensors (Temperature, Signal Strength etc) and potentially make changes to the behaviour of the system based on the readings from the sensors.
另外,每个传感器都可能连接到日志记录观察器以记录其当前状态,而监视器将连接到日志记录观察器以记录其决策
Additionally each sensor would possibly connect to a logging observer to log their current state and the monitor would connect to a logging observer to log its decisions
相同的设计模式将适用于我们介绍的任何新传感器,监视器或记录器.
The same design pattern would apply to any new sensor ,monitor or logger we introduce.
下面的示例代码:
using System;
using System.Threading;
using System.Collections.Generic;
namespace Soln
{
class MainClass
{
public static void Main (string[] args)
{
Console.WriteLine ("Hello World!");
var sensorA = new ASensor ();
sensorA.Start ();
var sensorB = new BSensor ();
sensorB.Start ();
var list = new List<ICustomEventHandler<string>> ();
list.Add (sensorA);
list.Add (sensorB);
var strObserver = new StringObserver (list);
strObserver.StartMonitor ();
Console.Read ();
sensorA.Stop ();
sensorB.Stop ();
}
}
//its a modular framework so every module implements
//this interface to interface to a core that loads them up etc
public interface IPlugin
{
bool Start();
void Stop();
}
public interface ICustomEventHandler<T>
{
event MyEventHandler<T> SomethingHappened;
}
//most sensors inherit from a base class and
//most create a thread to work in.
//The base interface also has an event that it uses to transmit
//notifications. The actual eventhandler is genericised so
//can be anything from a primitive to an actual object. Each plugin
//can additionally transmit multiply types but this is a basic example.
//hopefully once i can understand how rx works better , i can change the event handling to an IObservable interface
public abstract class Plugin<T>:IPlugin,ICustomEventHandler<T>
{
Thread oThread;
protected volatile bool _continueWorking = false;
#region IPlugin implementation
public bool Start ()
{
oThread = new Thread (DoWork);
_continueWorking = true;
oThread.Start ();
return true;
}
protected abstract void DoWork();
public void Stop ()
{
_continueWorking = false;
}
protected void RaiseEvent(T eventMessage)
{
if (SomethingHappened != null) {
SomethingHappened (eventMessage);
Console.WriteLine (eventMessage);
}
}
#endregion
public event MyEventHandler<T> SomethingHappened;
}
public class ASensor:Plugin<string>
{
protected override void DoWork()
{
//can't share the code for company reasons
while (_continueWorking) {
Console.WriteLine (" A doing some work");
Thread.Sleep (1000);
RaiseEvent ("ASensor has an event");
}
}
}
public delegate void MyEventHandler<T>(T foo);
public class BSensor:Plugin<string>
{
protected override void DoWork()
{
//can't share the code for company reasons
while (_continueWorking) {
Console.WriteLine ("B doing some work");
Thread.Sleep (1000);
RaiseEvent ("BSensor has an event");
}
}
}
//the observer should be strongly typed and take a list of
//plugins to monitor. At least those are my current thoughts,happy
//to find a better way. There could be multiple observers all monitoring
//the same plugins for different purposes
public abstract class Observer<T>
{
protected List<ICustomEventHandler<T>> Plugins;
protected Observer(List<ICustomEventHandler<T>> plugins)
{
Plugins = plugins;
}
//use rx to subscribe to all events
public abstract void StartMonitor ();
}
public class StringObserver:Observer<string>
{
public StringObserver(List<ICustomEventHandler<string>> plugins)
:base(plugins)
{
}
//subscribe to all plugin events in list using rx merge?
//monitor and log to file
public override void StartMonitor ()
{
//throw new NotImplementedException ();
}
}
}
感谢阅读
推荐答案
这不是一个直接的答案,但是它可能会让您知道代码可以到达的位置.
This isn't completely a direct answer, but it might give you some idea where your code can head.
因为您没有提供给我们传感器的代码,所以我无法真正为您提供具体的解决方案,但是如果您要求我将当前代码转换为Rx,那么我可能会执行以下操作:>
Because you haven't given us the code for your sensors I can't really give you a concrete solution, but if you asked me to convert your current code to Rx then I'd probably do something like this:
Func<string, IObservable<string>> generate = t =>
Observable.Interval(TimeSpan.FromSeconds(1.0)).Select(x => t);
var subject = new Subject<IObservable<string>>();
using (var subscription = subject.Merge().Subscribe(Console.WriteLine))
{
subject.OnNext(generate("A doing some work"));
subject.OnNext(generate("B doing some work"));
Console.ReadLine();
}
现在Func<string, IObservable<string>>
只是删除了一部分重复项,但是如果没有它,我可以在5行(包括Console.ReadLine();
)中复制代码的功能.
Now the Func<string, IObservable<string>>
was just a bit of duplication removal, but without it I can replicate the functionality of your code in 5 lines (which includes a Console.ReadLine();
).
您能告诉我们传感器代码吗?
Can you show us the sensor code please?
这篇关于使用RX构建传感器监控系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!