【问题标题】:Building a Sensor Monitoring System using RX使用 RX 构建传感器监控系统
【发布时间】:2016-04-19 15:36:33
【问题描述】:

请参阅Merging multiple custom observables in RX 了解背景信息。

我的情况是我有许多任意传感器(硬件)。我已经用 C# 编写了一些可以连接到这些传感器的可插拔模块。他们目前每个人都使用一个线程在计时器上运行采集例程。更大的目标是一旦我了解如何将轮询更改为 RX!

需要分组监控这些传感器,所以我想会有一个聚合主题,监控器可以订阅来自特定传感器组(温度、信号强度等)的更新,并可能对系统的行为基于来自传感器的读数。

此外,每个传感器可能会连接到日志观察器以记录其当前状态,监视器将连接到日志观察器以记录其决策

相同的设计模式适用于我们推出的任何新传感器、监视器或记录器。

示例代码如下:

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 ();
        }
    }
}

感谢阅读

【问题讨论】:

  • 你能显示代码吗?尤其是当前获取值和类定义的代码。
  • 您能否提供一个(最小、完整且可验证的示例)[stackoverflow.com/help/mcve],以便我们可以从某个地方开始?否则这感觉就像“你能不能给我写一个程序……”
  • @Enigmativity ,@Lee Campbell,对不起,我必须做一些其他的工作,我现在又回来了。周末会有事。再次感谢您的帮助和关注!
  • @Bernard - 只是对@ 通知系统的评论 - 你只能为一个人做一个@。任何后续的@ 都会被忽略。所以,你需要留下两次评论;每人一次。
  • @Enigmativity,添加了示例代码,如果仍然不清楚,很高兴添加更多内容。感谢阅读。

标签: linq system.reactive reactive-programming


【解决方案1】:

这并不完全是一个直接的答案,但它可能会让你知道你的代码可以去哪里。

因为你没有给我们传感器的代码,所以我不能真正给你一个具体的解决方案,但是如果你要求我将你当前的代码转换为 Rx,那么我可能会做这样的事情:

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&lt;string, IObservable&lt;string&gt;&gt; 只是删除了一些重复项,但没有它我可以在 5 行中复制您的代码的功能(其中包括 Console.ReadLine();)。

您能告诉我们传感器代码吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 2018-12-15
    • 1970-01-01
    • 2011-06-12
    相关资源
    最近更新 更多