LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C# 物联网设备监控系统实战:从零构建企业级数据采集平台

admin
2025年7月26日 7:6 本文热度 195

在制造业、智慧城市、农业物联网等领域每天都在上演。企业在物联网数据采集方面存在实时性、稳定性问题。如何构建一个高效、稳定的设备监控系统成为了每个.NET开发者必须面对的挑战。

今天,我将通过一个完整的C#物联网设备监控系统案例,手把手教你构建企业级的数据采集平台,解决实时监控、性能优化、数据可视化等核心问题。

🎯 项目背景与痛点分析

在实际的物联网项目中,我们经常遇到以下痛点:

🔥 核心痛点

  • 数据采集不稳定

    设备频繁掉线,数据丢失
  • 性能瓶颈

    大量设备同时上报数据,系统卡顿
  • 监控可视化困难

    缺乏直观的数据展示界面
  • 异常处理不完善

    设备故障时无法及时发现和处理

💼 业务需求

  • 支持多种类型的IoT设备(温度、湿度、压力传感器等)

  • 实时数据采集和展示

  • 设备状态监控和异常报警

  • 数据可视化图表展示

  • 性能监控和系统优化

🛠️ 技术方案设计

🏗️ 系统架构

​ 

🔧 核心技术栈

  • 并发处理

    ConcurrentDictionary确保线程安全
  • 定时任务

    Timer实现定时数据采集
  • 数据可视化

    ScottPlot绘制实时图表
  • 性能监控

    PerformanceCounter系统性能追踪
  • 异常处理

    完善的错误记录和恢复机制

💻 核心代码实现

🎯 IoT设备核心类设计

// IoT设备基础枚举定义
publicenum DeviceType
{
    TemperatureSensor,  // 温度传感器
    HumiditySensor,     // 湿度传感器
    PressureSensor,     // 压力传感器
    Motor,              // 电机
    Valve,              // 阀门
    Pump                // 泵
}

publicenum DeviceStatus
{
    Online,       // 在线
    Offline,      // 离线
    Error,        // 故障
    Maintenance   // 维护中
}

// 设备核心类 - 每个设备都是一个独立的数据生产者
publicclass IoTDevice
{

    publicstring DeviceId { get; set; }
    publicstring DeviceName { get; set; }
    public DeviceType DeviceType { get; set; }
    public DeviceStatus Status { get; set; }
    publicdouble? LastValue { get; set; }
    public DateTime LastUpdateTime { get; set; }

    private readonly Timer _dataTimer;
    private readonly Random _random = new Random();

    public IoTDevice(string deviceId, string deviceName, DeviceType deviceType)
    
{
        DeviceId = deviceId;
        DeviceName = deviceName;
        DeviceType = deviceType;
        Status = DeviceStatus.Offline;
        LastUpdateTime = DateTime.Now;

        // 🔥 关键设计:每个设备独立的数据生成定时器
        _dataTimer = new Timer();
        _dataTimer.Interval = 2000 + _random.Next(03000); // 2-5秒随机间隔
        _dataTimer.Tick += GenerateData;
    }

    private void GenerateData(object sender, EventArgs e)
    
{
        // 🎯 根据设备类型生成不同范围的模拟数据
        switch (DeviceType)
        {
            case DeviceType.TemperatureSensor:
                LastValue = 20 + _random.NextDouble() * 30// 20-50°C
                break;
            case DeviceType.HumiditySensor:
                LastValue = 30 + _random.NextDouble() * 40// 30-70%
                break;
            case DeviceType.PressureSensor:
                LastValue = 100 + _random.NextDouble() * 200// 100-300 kPa
                break;
            case DeviceType.Motor:
                LastValue = 1000 + _random.NextDouble() * 2000// 1000-3000 RPM
                break;
            default:
                LastValue = _random.NextDouble() * 100;
                break;
        }

        LastUpdateTime = DateTime.Now;

        // 🚨 模拟设备故障:2%概率出错,10%概率自动恢复
        if (_random.NextDouble() < 0.02)
        {
            Status = DeviceStatus.Error;
        }
        elseif (Status == DeviceStatus.Error && _random.NextDouble() < 0.1)
        {
            Status = DeviceStatus.Online;
        }
    }

    public void Start()
    
{
        Status = DeviceStatus.Online;
        _dataTimer.Start();
    }

    public void Stop()
    
{
        Status = DeviceStatus.Offline;
        _dataTimer.Stop();
    }
}

🎯 设备管理器 - 并发安全的核心

// 设备管理器 - 系统的核心控制器
publicclass IoTDeviceManager : IDisposable
{
    // 🔥 使用ConcurrentDictionary确保线程安全
    private readonly ConcurrentDictionary<string, IoTDevice> _devices;
    private readonly Timer _statsTimer;
    privatelong _totalDataPoints;
    private DateTime _lastStatsTime;

    public IoTDeviceManager()
    
{
        _devices = new ConcurrentDictionary<string, IoTDevice>();
        _lastStatsTime = DateTime.Now;

        // 统计定时器 - 每秒更新性能数据
        _statsTimer = new Timer();
        _statsTimer.Interval = 1000;
        _statsTimer.Tick += UpdateStats;
        _statsTimer.Start();
    }

    public void AddDevice(IoTDevice device)
    
{
        // 🎯 线程安全的设备添加
        _devices.TryAdd(device.DeviceId, device);
    }

    public IoTDevice GetDevice(string deviceId)
    
{
        _devices.TryGetValue(deviceId, out var device);
        return device;
    }

    public IEnumerable<IoTDevice> GetAllDevices()
    {
        return _devices.Values;
    }

    // 🚀 批量操作 - 提高执行效率
    public void StartAllDevices()
    
{
        Parallel.ForEach(_devices.Values, device => device.Start());
    }

    public void StopAllDevices()
    
{
        Parallel.ForEach(_devices.Values, device => device.Stop());
    }

    // 📊 实时计算数据采集速率
    public double GetDataRate()
    
{
        var now = DateTime.Now;
        var elapsed = (now - _lastStatsTime).TotalSeconds;
        var onlineDevices = _devices.Values.Count(d => d.Status == DeviceStatus.Online);

        return elapsed > 0 ? onlineDevices / 2.5 : 0// 平均每2.5秒一个数据点
    }

    private void UpdateStats(object sender, EventArgs e)
    
{
        _totalDataPoints += _devices.Values.Count(d => d.Status == DeviceStatus.Online);
        _lastStatsTime = DateTime.Now;
    }

    public void Dispose()
    
{
        _statsTimer?.Dispose();
        foreach (var device in _devices.Values)
        {
            device.Stop();
        }
    }
}

🎯 性能监控系统 - 企业级监控

// 性能监控收集器 - 实时追踪系统性能
publicclass MetricsCollector : IDisposable
{
    private readonly ConcurrentDictionary<string, OperationMetrics> _operationMetrics;
    private readonly ConcurrentDictionary<stringlong> _dataVolumes;
    private readonly ConcurrentQueue<ErrorRecord> _errors;

    public MetricsCollector()
    
{
        _operationMetrics = new ConcurrentDictionary<string, OperationMetrics>();
        _dataVolumes = new ConcurrentDictionary<stringlong>();
        _errors = new ConcurrentQueue<ErrorRecord>();
    }

    // 🎯 记录操作性能指标
    public void RecordProcessing(string operation, TimeSpan duration, bool success)
    
{
        _operationMetrics.AddOrUpdate(operation,
            new OperationMetrics
            {
                Count = 1,
                TotalDuration = duration,
                SuccessCount = success ? 1 : 0
            },
            (key, existing) => new OperationMetrics
            {
                Count = existing.Count + 1,
                TotalDuration = existing.TotalDuration + duration,
                SuccessCount = existing.SuccessCount + (success ? 1 : 0)
            });
    }

    // 📊 生成性能报告
    public PerformanceReport GenerateReport()
    
{
        var totalProcessed = _operationMetrics.Values.Sum(m => m.Count);
        var totalDuration = _operationMetrics.Values.Sum(m => m.TotalDuration.TotalMilliseconds);
        var totalSuccess = _operationMetrics.Values.Sum(m => m.SuccessCount);

        returnnew PerformanceReport
        {
            TimeWindow = TimeSpan.FromSeconds(10),
            TotalProcessed = totalProcessed,
            ProcessingRate = totalProcessed / 10.0,
            AverageLatency = totalProcessed > 0 ? totalDuration / totalProcessed : 0,
            ErrorRate = totalProcessed > 0 ? (double)(totalProcessed - totalSuccess) / totalProcessed : 0,
            MemoryUsage = GC.GetTotalMemory(false) / 1024 / 1024
        };
    }

    public void Dispose()
    
{
        // 清理资源
    }
}

// 性能报告数据结构
publicclass PerformanceReport
{

    public TimeSpan TimeWindow { get; set; }
    publiclong TotalProcessed { get; set; }
    publicdouble ProcessingRate { get; set; }  // 处理速率
    publicdouble AverageLatency { get; set; }  // 平均延迟
    publicdouble ErrorRate { get; set; }       // 错误率
    publiclong MemoryUsage { get; set; }       // 内存使用量
}

🎯 数据可视化实现

Nuget 安装ScottPlot.WinForms 5.0以上版本,这个版本变化较大。

using System.Collections.Concurrent;
using ScottPlot;
using System.Diagnostics;
using System.Text;
using Timer = System.Windows.Forms.Timer;
using ScottPlot.WinForms;

namespace AppIoTDeviceMonitor
{
    public partial class Form1 : Form
    {
        private readonly IoTDeviceManager _deviceManager;
        private readonly DataCollectionMonitor _monitor;
        private readonly Timer _refreshTimer;
        private readonly Random _random = new Random();

        // ScottPlot 数据存储
        private readonly ConcurrentQueue<(DateTime time, double temp)> _tempData = new();
        private readonly ConcurrentQueue<(DateTime time, double humidity)> _humidityData = new();
        private readonly ConcurrentQueue<(DateTime time, double pressure)> _pressureData = new();

        // ScottPlot 绘图对象
        private ScottPlot.Plottables.Scatter _tempPlot;
        private ScottPlot.Plottables.Scatter _humidityPlot;
        private ScottPlot.Plottables.Scatter _pressurePlot;

        privateconstint MAX_DATA_POINTS = 100;
        public Form1()
        
{
            InitializeComponent();
            _deviceManager = new IoTDeviceManager();
            _monitor = new DataCollectionMonitor();

            // 设置刷新定时器
            _refreshTimer = new Timer();
            _refreshTimer.Interval = 1000// 1秒刷新一次
            _refreshTimer.Tick += RefreshTimer_Tick;

            InitializeDevices();
            InitializeScottPlot();
            InitializeDataGridView();

            _refreshTimer.Start();

        }

        private void InitializeDevices()
        
{
            // 添加示例设备
            _deviceManager.AddDevice(new IoTDevice("TEMP_001""温度传感器1", DeviceType.TemperatureSensor));
            _deviceManager.AddDevice(new IoTDevice("TEMP_002""温度传感器2", DeviceType.TemperatureSensor));
            _deviceManager.AddDevice(new IoTDevice("HUM_001""湿度传感器1", DeviceType.HumiditySensor));
            _deviceManager.AddDevice(new IoTDevice("PRES_001""压力传感器1", DeviceType.PressureSensor));
            _deviceManager.AddDevice(new IoTDevice("MOTOR_001""电机1", DeviceType.Motor));

            // 启动所有设备
            _deviceManager.StartAllDevices();
        }

        private void InitializeScottPlot()
        
{
            // 设置图表基本属性
            formsPlot.Plot.Title("IoT设备实时数据监控");
            formsPlot.Plot.XLabel("时间");
            formsPlot.Plot.YLabel("数值");
            formsPlot.Plot.Font.Set("SimSun");

            // 设置背景色
            formsPlot.Plot.FigureBackground.Color = ScottPlot.Color.FromHex("#FAFAFA");
            formsPlot.Plot.DataBackground.Color = ScottPlot.Color.FromHex("#FAFAFA");

            // 配置坐标轴
            formsPlot.Plot.Axes.DateTimeTicksBottom();
            formsPlot.Plot.Axes.AutoScale();

            // 创建数据系列
            _tempPlot = formsPlot.Plot.Add.Scatter(newdouble[0], newdouble[0]);
            _tempPlot.Color = ScottPlot.Color.FromHex("#FF0000");
            _tempPlot.LineWidth = 2;
            _tempPlot.MarkerSize = 3;
            _tempPlot.LegendText = "温度 (°C)";

            _humidityPlot = formsPlot.Plot.Add.Scatter(newdouble[0], newdouble[0]);
            _humidityPlot.Color = ScottPlot.Color.FromHex("#0000FF"); ;
            _humidityPlot.LineWidth = 2;
            _humidityPlot.MarkerSize = 3;
            _humidityPlot.LegendText = "湿度 (%)";

            _pressurePlot = formsPlot.Plot.Add.Scatter(newdouble[0], newdouble[0]);
            _pressurePlot.Color = ScottPlot.Color.FromHex("#008000"); ;
            _pressurePlot.LineWidth = 2;
            _pressurePlot.MarkerSize = 3;
            _pressurePlot.LegendText = "压力 (kPa)";

            // 显示图例
            formsPlot.Plot.ShowLegend(Alignment.UpperLeft);

            // 设置网格
            formsPlot.Plot.Grid.MajorLineColor = ScottPlot.Color.FromHex("#C8C8C8");
            formsPlot.Plot.Grid.MinorLineColor = ScottPlot.Color.FromHex("#E6E6E6");

            // 初始刷新
            formsPlot.Refresh();
        }

        private void InitializeDataGridView()
        
{
            dgvDevices.AutoGenerateColumns = false;
            dgvDevices.Columns.Add("DeviceId""设备ID");
            dgvDevices.Columns.Add("DeviceName""设备名称");
            dgvDevices.Columns.Add("DeviceType""设备类型");
            dgvDevices.Columns.Add("Status""状态");
            dgvDevices.Columns.Add("LastValue""最新值");
            dgvDevices.Columns.Add("LastUpdate""最后更新");

            // 设置列宽
            dgvDevices.Columns[0].Width = 100;
            dgvDevices.Columns[1].Width = 120;
            dgvDevices.Columns[2].Width = 100;
            dgvDevices.Columns[3].Width = 80;
            dgvDevices.Columns[4].Width = 80;
            dgvDevices.Columns[5].Width = 140;
        }

        private void RefreshTimer_Tick(object sender, EventArgs e)
        
{
            UpdateDeviceStatus();
            UpdateScottPlot();
            UpdatePerformanceMetrics();
        }

        private void UpdateDeviceStatus()
        
{
            dgvDevices.Rows.Clear();

            foreach (var device in _deviceManager.GetAllDevices())
            {
                var row = new DataGridViewRow();
                row.CreateCells(dgvDevices);

                row.Cells[0].Value = device.DeviceId;
                row.Cells[1].Value = device.DeviceName;
                row.Cells[2].Value = device.DeviceType.ToString();
                row.Cells[3].Value = device.Status.ToString();
                row.Cells[4].Value = device.LastValue?.ToString("F2") ?? "-";
                row.Cells[5].Value = device.LastUpdateTime.ToString("yyyy-MM-dd HH:mm:ss");

                // 根据状态设置行颜色
                if (device.Status == DeviceStatus.Online)
                    row.DefaultCellStyle.BackColor = System.Drawing.Color.LightGreen;
                elseif (device.Status == DeviceStatus.Error)
                    row.DefaultCellStyle.BackColor = System.Drawing.Color.LightPink;
                else
                    row.DefaultCellStyle.BackColor = System.Drawing.Color.LightGray;

                dgvDevices.Rows.Add(row);
            }
        }

        private void UpdateScottPlot()
        
{
            var now = DateTime.Now;

            // 获取并添加温度数据
            var tempDevice = _deviceManager.GetDevice("TEMP_001");
            if (tempDevice != null && tempDevice.LastValue.HasValue)
            {
                _tempData.Enqueue((now, tempDevice.LastValue.Value));

                // 限制数据点数量
                while (_tempData.Count > MAX_DATA_POINTS)
                {
                    _tempData.TryDequeue(out _);
                }
            }

            // 获取并添加湿度数据
            var humDevice = _deviceManager.GetDevice("HUM_001");
            if (humDevice != null && humDevice.LastValue.HasValue)
            {
                _humidityData.Enqueue((now, humDevice.LastValue.Value));

                while (_humidityData.Count > MAX_DATA_POINTS)
                {
                    _humidityData.TryDequeue(out _);
                }
            }

            // 获取并添加压力数据
            var presDevice = _deviceManager.GetDevice("PRES_001");
            if (presDevice != null && presDevice.LastValue.HasValue)
            {
                _pressureData.Enqueue((now, presDevice.LastValue.Value));

                while (_pressureData.Count > MAX_DATA_POINTS)
                {
                    _pressureData.TryDequeue(out _);
                }
            }

            // 更新图表数据
            UpdatePlotData();
        }

        private void UpdatePlotData()
        
{
            // 更新温度数据
            if (_tempData.Count > 0)
            {
                var tempArray = _tempData.ToArray();
                var tempX = tempArray.Select(d => d.time.ToOADate()).ToArray();
                var tempY = tempArray.Select(d => d.temp).ToArray();

                // 移除旧的图表并添加新的
                formsPlot.Plot.Remove(_tempPlot);
                _tempPlot = formsPlot.Plot.Add.Scatter(tempX, tempY);
                _tempPlot.Color = ScottPlot.Color.FromHex("#FF0000");
                _tempPlot.LineWidth = 2;
                _tempPlot.MarkerSize = 3;
                _tempPlot.LegendText = "温度 (°C)";
            }

            // 更新湿度数据
            if (_humidityData.Count > 0)
            {
                var humArray = _humidityData.ToArray();
                var humX = humArray.Select(d => d.time.ToOADate()).ToArray();
                var humY = humArray.Select(d => d.humidity).ToArray();

                formsPlot.Plot.Remove(_humidityPlot);
                _humidityPlot = formsPlot.Plot.Add.Scatter(humX, humY);
                _humidityPlot.Color = ScottPlot.Color.FromHex("#0000FF");
                _humidityPlot.LineWidth = 2;
                _humidityPlot.MarkerSize = 3;
                _humidityPlot.LegendText = "湿度 (%)";
            }

            // 更新压力数据
            if (_pressureData.Count > 0)
            {
                var presArray = _pressureData.ToArray();
                var presX = presArray.Select(d => d.time.ToOADate()).ToArray();
                var presY = presArray.Select(d => d.pressure).ToArray();

                formsPlot.Plot.Remove(_pressurePlot);
                _pressurePlot = formsPlot.Plot.Add.Scatter(presX, presY);
                _pressurePlot.Color = ScottPlot.Color.FromHex("#008000");
                _pressurePlot.LineWidth = 2;
                _pressurePlot.MarkerSize = 3;
                _pressurePlot.LegendText = "压力 (kPa)";
            }

            // 重新显示图例
            formsPlot.Plot.ShowLegend(Alignment.UpperLeft);

            // 自动缩放并刷新
            formsPlot.Plot.Axes.AutoScale();
            formsPlot.Refresh();
        }

        private void UpdatePerformanceMetrics()
        
{
            // 更新性能指标显示
            var totalDevices = _deviceManager.GetAllDevices().Count();
            var onlineDevices = _deviceManager.GetAllDevices().Count(d => d.Status == DeviceStatus.Online);
            var errorDevices = _deviceManager.GetAllDevices().Count(d => d.Status == DeviceStatus.Error);

            lblTotalDevices.Text = $"总设备数: {totalDevices}";
            lblOnlineDevices.Text = $"在线设备: {onlineDevices}";
            lblErrorDevices.Text = $"故障设备: {errorDevices}";

            // 更新系统性能
            var process = Process.GetCurrentProcess();
            lblMemoryUsage.Text = $"内存使用: {process.WorkingSet64 / 1024 / 1024:F1} MB";
            lblCpuUsage.Text = $"CPU使用率: {GetCpuUsage():F1}%";

            // 更新数据采集速率
            lblDataRate.Text = $"数据采集速率: {_deviceManager.GetDataRate():F0} 条/秒";
        }

        private double GetCpuUsage()
        
{
            // 简单的CPU使用率计算
            return _random.NextDouble() * 20 + 10// 模拟10-30%的CPU使用率
        }

        private void btnStartMonitoring_Click(object sender, EventArgs e)
        
{
            _deviceManager.StartAllDevices();
            _refreshTimer.Start();
            btnStartMonitoring.Enabled = false;
            btnStopMonitoring.Enabled = true;
            MessageBox.Show("监控已启动""信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void btnStopMonitoring_Click(object sender, EventArgs e)
        
{
            _deviceManager.StopAllDevices();
            _refreshTimer.Stop();
            btnStartMonitoring.Enabled = true;
            btnStopMonitoring.Enabled = false;
            MessageBox.Show("监控已停止""信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void btnResetChart_Click(object sender, EventArgs e)
        
{
            // 清空所有数据
            while (_tempData.TryDequeue(out _)) { }
            while (_humidityData.TryDequeue(out _)) { }
            while (_pressureData.TryDequeue(out _)) { }

            // 完全清空图表并重新初始化
            formsPlot.Plot.Clear();
            InitializeScottPlot();

            MessageBox.Show("图表已重置""信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void btnExportData_Click(object sender, EventArgs e)
        
{
            var saveDialog = new SaveFileDialog
            {
                Filter = "CSV files (*.csv)|*.csv",
                Title = "导出设备数据"
            };

            if (saveDialog.ShowDialog() == DialogResult.OK)
            {
                ExportDeviceData(saveDialog.FileName);
                MessageBox.Show("数据导出成功""信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void ExportDeviceData(string fileName)
        
{
            var csv = new StringBuilder();
            csv.AppendLine("设备ID,设备名称,设备类型,状态,最新值,最后更新时间");

            foreach (var device in _deviceManager.GetAllDevices())
            {
                csv.AppendLine($"{device.DeviceId},{device.DeviceName},{device.DeviceType}," +
                             $"{device.Status},{device.LastValue},{device.LastUpdateTime}");
            }

            System.IO.File.WriteAllText(fileName, csv.ToString(), Encoding.UTF8);
        }

        private void btnZoomIn_Click(object sender, EventArgs e)
        
{
            formsPlot.Plot.Axes.Zoom(0.80.8);
            formsPlot.Refresh();
        }

        private void btnZoomOut_Click(object sender, EventArgs e)
        
{
            formsPlot.Plot.Axes.Zoom(1.21.2);
            formsPlot.Refresh();
        }

        private void btnAutoScale_Click(object sender, EventArgs e)
        
{
            formsPlot.Plot.Axes.AutoScale();
            formsPlot.Refresh();
        }

        private void btnSaveChart_Click(object sender, EventArgs e)
        
{
            var saveDialog = new SaveFileDialog
            {
                Filter = "PNG files (*.png)|*.png|JPEG files (*.jpg)|*.jpg",
                Title = "保存图表"
            };

            if (saveDialog.ShowDialog() == DialogResult.OK)
            {
                formsPlot.Plot.Save(saveDialog.FileName, formsPlot.Width, formsPlot.Height);
                MessageBox.Show("图表已保存""信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        
{
            _refreshTimer?.Stop();
            _deviceManager?.Dispose();
            _monitor?.Dispose();
            base.OnFormClosing(e);
        }
    }
}

🔧 核心技术点深度解析

🎯 1. 并发处理最佳实践

// ✅ 正确使用:ConcurrentDictionary保证线程安全
private readonly ConcurrentDictionary<string, IoTDevice> _devices;

// ❌ 错误用法:普通Dictionary在多线程环境下不安全
// private readonly Dictionary<string, IoTDevice> _devices;

// 🔥 性能优化:使用Parallel.ForEach并行处理
public void StartAllDevices()
{
    Parallel.ForEach(_devices.Values, device => device.Start());
}

🎯 2. 内存管理策略

// 🚨 关键:限制数据点数量防止内存溢出
private const int MAX_DATA_POINTS = 100;

while (_tempData.Count > MAX_DATA_POINTS)
{
    _tempData.TryDequeue(out _); // 移除旧数据
}

🎯 3. 异常处理机制

// 🔄 设备自动恢复机制
if (_random.NextDouble() < 0.02// 2%概率故障
{
    Status = DeviceStatus.Error;
}
else if (Status == DeviceStatus.Error && _random.NextDouble() < 0.1// 10%概率恢复
{
    Status = DeviceStatus.Online;
}

🎯 性能优化建议

🔥 内存优化

// 定期清理过期数据
private void CleanupOldData()
{
    var cutoffTime = DateTime.Now.AddMinutes(-10);
    while (_tempData.Count > 0 && _tempData.First().time < cutoffTime)
    {
        _tempData.TryDequeue(out _);
    }
}

⚡ 处理速度优化

// 使用缓存减少重复计算
private readonly ConcurrentDictionary<stringdouble> _dataCache = new();

// 批量处理数据
public void ProcessBatch(List<DeviceData> dataList)
{
    Parallel.ForEach(dataList, data => ProcessSingleData(data));
}

📊 关键指标监控

🎯 系统性能指标

  • 处理速率

    数据处理每秒条数
  • 平均延迟

    从数据产生到显示的时间
  • 错误率

    数据处理失败的比例
  • 内存使用

    系统内存消耗监控

🔍 业务指标

  • 设备在线率

    在线设备数量/总设备数量
  • 数据完整性

    成功采集的数据比例
  • 响应时间

    用户操作响应时间

🎊 总结与展望

通过这个完整的IoT设备监控系统案例,我们学习了:

🔥 三大核心技术

  1. 并发安全处理

    使用ConcurrentDictionaryParallel.ForEach确保多线程环境下的数据安全
  2. 实时数据可视化

    利用ScottPlot实现专业级的数据图表展示
  3. 性能监控优化

    通过MetricsCollector实现系统性能的实时追踪

💡 实战价值

  • 直接应用

    代码可直接用于实际项目开发
  • 架构参考

    提供了完整的IoT系统架构设计思路
  • 最佳实践

    包含了内存管理、异常处理、性能优化等最佳实践


阅读原文:原文链接


该文章在 2025/7/26 9:10:25 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved