我将提供基于 .NET 8.0-windows7.0 的半导体可靠性测试机上位机系统的 硬件驱动 和 数据存储 模块的详细代码实现。代码将与之前的 UI 框架(WPF、Prism、MVVM、MaterialDesignThemes、LiveCharts 2)无缝集成,涵盖硬件驱动的抽象接口、不同协议(串口、TCP/UDP、Modbus)支持,以及数据存储的 CSV、SQLite 和 MySQL 实现。以下内容包含详细的代码示例、中文注释和实现说明,确保模块化、可扩展和高性能,满足半导体测试场景的需求。
一、硬件驱动设计
1.1 设计目标
抽象化:通过接口和抽象类定义硬件通用操作(初始化、开启、关闭、设置、读取),支持不同厂商硬件(如 Tektronix 电源、自定义温箱)。
多协议支持:实现串口(COM)、TCP/UDP 和 Modbus 协议,兼容主流通信方式。
可扩展性:使用依赖注入(Autofac)和反射动态加载驱动,支持硬件切换。
事件驱动:硬件状态变化触发事件,通知 UI 或其他模块。
异步操作:使用 async/await 确保高性能,适合高频数据采集。
1.2 项目结构
SemiconductorTestSystem/
├── SemiconductorTestSystem.Hardware/
│ ├── Interfaces/
│ │ ├── IHardwareDevice.cs
│ │ ├── ICommunication.cs
│ ├── Drivers/
│ │ ├── TektronixPowerSupply.cs
│ │ ├── CustomOven.cs
│ │ ├── ModbusDevice.cs
│ ├── Communication/
│ │ ├── SerialPortCommunication.cs
│ │ ├── TcpCommunication.cs
│ │ ├── UdpCommunication.cs
│ │ ├── ModbusCommunication.cs
│ ├── Services/
│ │ ├── HardwareService.cs
│ ├── HardwareModule.cs
1.3 硬件抽象接口
IHardwareDevice.cs
定义硬件设备的通用接口。
csharp
using System;
namespace SemiconductorTestSystem.Hardware.Interfaces
{
public interface IHardwareDevice : IDisposable
{
string DeviceId { get; }
string DeviceName { get; }
DeviceStatus Status { get; }
Task InitializeAsync();
Task StartAsync();
Task StopAsync();
Task SetParameterAsync(string parameter, object value);
Task
说明:
属性:DeviceId 唯一标识设备,DeviceName 显示名称,Status 表示当前状态。
方法:异步操作(InitializeAsync、StartAsync 等)确保非阻塞。
事件:StatusChanged 通知状态变化,供 UI 或日志模块订阅。
ICommunication.cs
定义通信协议的通用接口。
csharp
namespace SemiconductorTestSystem.Hardware.Interfaces
{
public interface ICommunication : IDisposable
{
Task ConnectAsync();
Task DisconnectAsync();
Task SendAsync(string command);
Task ReceiveAsync();
}
}
说明:
抽象通信层,支持串口、TCP/UDP、Modbus 等协议。
异步方法确保高性能通信。
1.4 通信协议实现
SerialPortCommunication.cs(串口通信)
csharp
using System.IO.Ports;
using System.Threading.Tasks;
using SemiconductorTestSystem.Hardware.Interfaces;
namespace SemiconductorTestSystem.Hardware.Communication
{
public class SerialPortCommunication : ICommunication
{
private readonly SerialPort _serialPort;
public SerialPortCommunication(string portName, int baudRate = 9600)
{
_serialPort = new SerialPort(portName, baudRate)
{
ReadTimeout = 5000,
WriteTimeout = 5000
};
}
public async Task ConnectAsync()
{
await Task.Run(() =>
{
if (!_serialPort.IsOpen)
{
_serialPort.Open();
}
});
}
public async Task DisconnectAsync()
{
await Task.Run(() =>
{
if (_serialPort.IsOpen)
{
_serialPort.Close();
}
});
}
public async Task SendAsync(string command)
{
await Task.Run(() => _serialPort.WriteLine(command));
}
public async Task ReceiveAsync()
{
return await Task.Run(() => _serialPort.ReadLine());
}
public void Dispose()
{
_serialPort?.Dispose();
}
}
}
说明:
使用 System.IO.Ports.SerialPort 实现串口通信。
异步方法避免阻塞,适合高频数据采集。
TcpCommunication.cs(TCP 通信)
csharp
using System.Net.Sockets;
using System.Text;
namespace SemiconductorTestSystem.Hardware.Communication
{
public class TcpCommunication : ICommunication
{
private readonly TcpClient _client;
private NetworkStream _stream;
public TcpCommunication(string ipAddress, int port)
{
_client = new TcpClient();
_client.ReceiveTimeout = 5000;
_client.SendTimeout = 5000;
IpAddress = ipAddress;
Port = port;
}
public string IpAddress { get; }
public int Port { get; }
public async Task ConnectAsync()
{
await _client.ConnectAsync(IpAddress, Port);
_stream = _client.GetStream();
}
public async Task DisconnectAsync()
{
await Task.Run(() =>
{
_stream?.Close();
_client?.Close();
});
}
public async Task SendAsync(string command)
{
byte[] data = Encoding.ASCII.GetBytes(command + "\r\n");
await _stream.WriteAsync(data, 0, data.Length);
}
public async Task ReceiveAsync()
{
byte[] buffer = new byte[1024];
int bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length);
return Encoding.ASCII.GetString(buffer, 0, bytesRead).Trim();
}
public void Dispose()
{
_stream?.Dispose();
_client?.Dispose();
}
}
}
说明:
使用 TcpClient 实现 TCP 通信,异步方法确保高效。
支持配置 IP 地址和端口,适配不同设备。
ModbusCommunication.cs(Modbus 通信)
csharp
using Modbus.Device;
using System.Net.Sockets;
using System.Threading.Tasks;
using SemiconductorTestSystem.Hardware.Interfaces;
namespace SemiconductorTestSystem.Hardware.Communication
{
public class ModbusCommunication : ICommunication
{
private readonly string _ipAddress;
private readonly int _port;
private ModbusIpMaster _master;
private TcpClient _client;
public ModbusCommunication(string ipAddress, int port = 502)
{
_ipAddress = ipAddress;
_port = port;
}
public async Task ConnectAsync()
{
_client = new TcpClient();
await _client.ConnectAsync(_ipAddress, _port);
_master = ModbusIpMaster.CreateIp(_client);
}
public async Task DisconnectAsync()
{
await Task.Run(() =>
{
_master?.Dispose();
_client?.Close();
});
}
public async Task SendAsync(string command)
{
// 示例:写入寄存器
ushort address = ushort.Parse(command.Split(':')[0]);
ushort value = ushort.Parse(command.Split(':')[1]);
await _master.WriteSingleRegisterAsync(1, address, value);
}
public async Task ReceiveAsync()
{
// 示例:读取寄存器
ushort[] registers = await _master.ReadHoldingRegistersAsync(1, 0, 1);
return registers[0].ToString();
}
public void Dispose()
{
_master?.Dispose();
_client?.Dispose();
}
}
}
说明:
使用 Modbus.Device(需安装 NuGet 包 NModbus)实现 Modbus TCP 协议。
支持读写寄存器,适配工业设备。
1.5 具体驱动实现
TektronixPowerSupply.cs(电源驱动)
csharp
using System.Threading.Tasks;
using SemiconductorTestSystem.Hardware.Interfaces;
using SemiconductorTestSystem.Hardware.Communication;
namespace SemiconductorTestSystem.Hardware.Drivers
{
public class TektronixPowerSupply : IHardwareDevice
{
private readonly ICommunication _communication;
private DeviceStatus _status;
public TektronixPowerSupply(ICommunication communication)
{
_communication = communication;
DeviceId = Guid.NewGuid().ToString();
DeviceName = "Tektronix Power Supply";
_status = DeviceStatus.Disconnected;
}
public string DeviceId { get; }
public string DeviceName { get; }
public DeviceStatus Status => _status;
public event EventHandler StatusChanged;
public async Task InitializeAsync()
{
try
{
await _communication.ConnectAsync();
_status = DeviceStatus.Idle;
RaiseStatusChanged("Initialized successfully");
}
catch (Exception ex)
{
_status = DeviceStatus.Error;
RaiseStatusChanged($"Initialization failed: {ex.Message}");
}
}
public async Task StartAsync()
{
try
{
await _communication.SendAsync("OUTPUT ON");
_status = DeviceStatus.Running;
RaiseStatusChanged("Started");
}
catch (Exception ex)
{
_status = DeviceStatus.Error;
RaiseStatusChanged($"Start failed: {ex.Message}");
}
}
public async Task StopAsync()
{
try
{
await _communication.SendAsync("OUTPUT OFF");
_status = DeviceStatus.Idle;
RaiseStatusChanged("Stopped");
}
catch (Exception ex)
{
_status = DeviceStatus.Error;
RaiseStatusChanged($"Stop failed: {ex.Message}");
}
}
public async Task SetParameterAsync(string parameter, object value)
{
try
{
if (parameter == "Voltage")
{
await _communication.SendAsync($"VOLT {value}");
}
else if (parameter == "Current")
{
await _communication.SendAsync($"CURR {value}");
}
}
catch (Exception ex)
{
_status = DeviceStatus.Error;
RaiseStatusChanged($"Set parameter failed: {ex.Message}");
}
}
public async Task
说明:
支持串口或 TCP 通信,通过注入 ICommunication 实现。
异步操作确保高效,事件通知状态变化。
CustomOven.cs(温箱驱动)
csharp
using System.Threading.Tasks;
using SemiconductorTestSystem.Hardware.Interfaces;
using SemiconductorTestSystem.Hardware.Communication;
namespace SemiconductorTestSystem.Hardware.Drivers
{
public class CustomOven : IHardwareDevice
{
private readonly ICommunication _communication;
private DeviceStatus _status;
public CustomOven(ICommunication communication)
{
_communication = communication;
DeviceId = Guid.NewGuid().ToString();
DeviceName = "Custom Oven";
_status = DeviceStatus.Disconnected;
}
public string DeviceId { get; }
public string DeviceName { get; }
public DeviceStatus Status => _status;
public event EventHandler StatusChanged;
public async Task InitializeAsync()
{
try
{
await _communication.ConnectAsync();
_status = DeviceStatus.Idle;
RaiseStatusChanged("Initialized successfully");
}
catch (Exception ex)
{
_status = DeviceStatus.Error;
RaiseStatusChanged($"Initialization failed: {ex.Message}");
}
}
public async Task StartAsync()
{
try
{
await _communication.SendAsync("START");
_status = DeviceStatus.Running;
RaiseStatusChanged("Started");
}
catch (Exception ex)
{
_status = DeviceStatus.Error;
RaiseStatusChanged($"Start failed: {ex.Message}");
}
}
public async Task StopAsync()
{
try
{
await _communication.SendAsync("STOP");
_status = DeviceStatus.Idle;
RaiseStatusChanged("Stopped");
}
catch (Exception ex)
{
_status = DeviceStatus.Error;
RaiseStatusChanged($"Stop failed: {ex.Message}");
}
}
public async Task SetParameterAsync(string parameter, object value)
{
try
{
if (parameter == "Temperature")
{
await _communication.SendAsync($"TEMP {value}");
}
}
catch (Exception ex)
{
_status = DeviceStatus.Error;
RaiseStatusChanged($"Set parameter failed: {ex.Message}");
}
}
public async Task
说明:
温箱驱动示例,支持温度设置和读取。
使用相同的 ICommunication 接口,支持协议切换。
1.6 硬件服务(动态加载)
HardwareService.cs
csharp
using System.Reflection;
using Microsoft.Extensions.Configuration;
using Autofac;
using SemiconductorTestSystem.Hardware.Interfaces;
using SemiconductorTestSystem.Hardware.Communication;
namespace SemiconductorTestSystem.Hardware.Services
{
public class HardwareService : IHardwareService
{
private readonly IConfiguration _configuration;
private readonly ILifetimeScope _scope;
private readonly Dictionary _devices;
public HardwareService(IConfiguration configuration, ILifetimeScope scope)
{
_configuration = configuration;
_scope = scope;
_devices = new Dictionary();
LoadDevices();
}
private void LoadDevices()
{
var hardwareConfig = _configuration.GetSection("Hardware");
foreach (var deviceConfig in hardwareConfig.GetChildren())
{
var typeName = deviceConfig["Type"];
var protocol = deviceConfig["Protocol"];
ICommunication communication = protocol switch
{
"Serial" => new SerialPortCommunication(deviceConfig["Port"], int.Parse(deviceConfig["BaudRate"] ?? "9600")),
"TCP" => new TcpCommunication(deviceConfig["Address"], int.Parse(deviceConfig["Port"])),
"Modbus" => new ModbusCommunication(deviceConfig["Address"], int.Parse(deviceConfig["Port"] ?? "502")),
_ => throw new ArgumentException($"Unsupported protocol: {protocol}")
};
var deviceType = Type.GetType($"SemiconductorTestSystem.Hardware.Drivers.{typeName}");
if (deviceType != null)
{
var device = (IHardwareDevice)Activator.CreateInstance(deviceType, communication);
_devices.Add(deviceConfig.Key, device);
}
}
}
public async Task> GetAllDevicesAsync()
{
return await Task.FromResult(_devices.Values.ToList());
}
public async Task GetDeviceAsync(string deviceName)
{
return await Task.FromResult(_devices.Values.FirstOrDefault(d => d.DeviceName == deviceName));
}
}
public interface IHardwareService
{
Task> GetAllDevicesAsync();
Task GetDeviceAsync(string deviceName);
}
}
说明:
通过配置文件动态加载硬件驱动和通信协议。
使用 Autofac 的 ILifetimeScope 管理依赖。
支持串口、TCP 和 Modbus 协议切换。
appsettings.json
json
{
"Hardware": {
"PowerSupply": {
"Type": "TektronixPowerSupply",
"Protocol": "Serial",
"Port": "COM1",
"BaudRate": "9600"
},
"Oven": {
"Type": "CustomOven",
"Protocol": "TCP",
"Address": "192.168.1.100 молодежь
"Port": "5020"
},
"ModbusDevice": {
"Type": "ModbusDevice",
"Protocol": "Modbus",
"Address": "192.168.1.101",
"Port": "502"
}
}
}
HardwareModule.cs(Autofac 注册)
csharp
using Autofac;
using SemiconductorTestSystem.Hardware.Interfaces;
using SemiconductorTestSystem.Hardware.Services;
namespace SemiconductorTestSystem.Hardware
{
public class HardwareModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType().As().SingleInstance();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
}
}
}
说明:
Autofac 模块注册硬件服务和驱动。
支持动态加载不同厂商的硬件。
二、数据存储设计
2.1 设计目标
多存储支持:支持 CSV、SQLite 和 MySQL,通过配置文件切换。
灵活性:CSV 支持自定义格式,通过反射实现。
高性能:使用 Entity Framework Core 优化数据库操作,异步存储数据。
可扩展性:抽象存储接口,方便添加新存储方式(如 PostgreSQL)。
2.2 项目结构
SemiconductorTestSystem/
├── SemiconductorTestSystem.Data/
│ ├── Interfaces/
│ │ ├── IDataStorageService.cs
│ ├── Repositories/
│ │ ├── CsvStorageProvider.cs
│ │ ├── DatabaseStorageProvider.cs
│ ├── DbContexts/
│ │ ├── TestDbContext.cs
│ ├── Models/
│ │ ├── TestData.cs
│ │ ├── Channel.cs
│ ├── DataModule.cs
2.3 数据模型
TestData.cs
csharp
namespace SemiconductorTestSystem.Data.Models
{
public class TestData
{
public int Id { get; set; }
public string ChannelId { get; set; }
public DateTime Timestamp { get; set; }
public double Temperature { get; set; }
public double Voltage { get; set; }
public double Current { get; set; }
public string TestMode { get; set; }
}
}
Channel.cs
csharp
namespace SemiconductorTestSystem.Data.Models
{
public class Channel
{
public string Id { get; set; }
public string ChannelName { get; set; }
public string OvenId { get; set; }
public string ZoneId { get; set; }
public string Status { get; set; }
}
}
2.4 存储接口
IDataStorageService.cs
csharp
using SemiconductorTestSystem.Data.Models;
namespace SemiconductorTestSystem.Data.Interfaces
{
public interface IDataStorageService
{
Task SaveDataAsync(IEnumerable data);
Task> QueryDataAsync(string channelId, DateTime? startTime, DateTime? endTime);
}
}
2.5 存储实现
CsvStorageProvider.cs
csharp
using System.Reflection;
using System.IO;
using System.Threading.Tasks;
using SemiconductorTestSystem.Data.Interfaces;
namespace SemiconductorTestSystem.Data.Repositories
{
public class CsvStorageProvider : IDataStorageService
{
private readonly string _filePath;
private readonly Type _dataType;
public CsvStorageProvider(string filePath, Type dataType)
{
_filePath = filePath;
_dataType = dataType;
}
public async Task SaveDataAsync(IEnumerable data)
{
using var writer = new StreamWriter(_filePath, append: true);
var properties = _dataType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
// 写入表头(仅在文件为空时)
if (new FileInfo(_filePath).Length == 0)
{
await writer.WriteLineAsync(string.Join(",", properties.Select(p => p.Name)));
}
// 写入数据
foreach (var item in data)
{
var values = properties.Select(p => p.GetValue(item)?.ToString() ?? "");
await writer.WriteLineAsync(string.Join(",", values));
}
}
public async Task> QueryDataAsync(string channelId, DateTime? startTime, DateTime? endTime)
{
var results = new List();
using var reader = new StreamReader(_filePath);
var headers = (await reader.ReadLineAsync()).Split(',');
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync();
var values = line.Split(',');
var data = new TestData
{
Id = int.Parse(values[0]),
ChannelId = values[1],
Timestamp = DateTime.Parse(values[2]),
Temperature = double.Parse(values[3]),
Voltage = double.Parse(values[4]),
Current = double.Parse(values[5]),
TestMode = values[6]
};
if (data.ChannelId == channelId &&
(!startTime.HasValue || data.Timestamp >= startTime) &&
(!endTime.HasValue || data.Timestamp <= endTime))
{
results.Add(data);
}
}
return results;
}
}
}
说明:
使用反射动态写入和读取 CSV 文件,支持自定义格式。
异步 I/O 提高性能。
DatabaseStorageProvider.cs
csharp
using Microsoft.EntityFrameworkCore;
using SemiconductorTestSystem.Data.DbContexts;
using SemiconductorTestSystem.Data.Models;
using System.Linq;
namespace SemiconductorTestSystem.Data.Repositories
{
public class DatabaseStorageProvider : IDataStorageService
{
private readonly TestDbContext _dbContext;
public DatabaseStorageProvider(TestDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task SaveDataAsync(IEnumerable data)
{
if (typeof(T) == typeof(TestData))
{
await _dbContext.TestDatas.AddRangeAsync(data.Cast());
await _dbContext.SaveChangesAsync();
}
}
public async Task> QueryDataAsync(string channelId, DateTime? startTime, DateTime? endTime)
{
var query = _dbContext.TestDatas.AsQueryable();
if (!string.IsNullOrEmpty(channelId))
{
query = query.Where(d => d.ChannelId == channelId);
}
if (startTime.HasValue)
{
query = query.Where(d => d.Timestamp >= startTime.Value);
}
if (endTime.HasValue)
{
query = query.Where(d => d.Timestamp <= endTime.Value);
}
return await query.ToListAsync();
}
}
}
TestDbContext.cs
csharp
using Microsoft.EntityFrameworkCore;
using SemiconductorTestSystem.Data.Models;
namespace SemiconductorTestSystem.Data.DbContexts
{
public class TestDbContext : DbContext
{
public DbSet TestDatas { get; set; }
public DbSet Channels { get; set; }
public TestDbContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity().HasKey(t => t.Id);
modelBuilder.Entity().HasKey(c => c.Id);
}
}
}
说明:
使用 EF Core 支持 SQLite 和 MySQL。
异步查询和保存提高性能。
2.6 数据服务
DataService.cs
csharp
using Microsoft.Extensions.Configuration;
using SemiconductorTestSystem.Data.Interfaces;
using SemiconductorTestSystem.Data.Repositories;
using SemiconductorTestSystem.Data.DbContexts;
namespace SemiconductorTestSystem.Data.Services
{
public class DataService : IDataStorageService
{
private readonly IDataStorageService _provider;
public DataService(IConfiguration configuration, TestDbContext dbContext)
{
var storageType = configuration["Storage:Type"];
var connectionString = configuration["Storage:ConnectionString"];
_provider = storageType switch
{
"CSV" => new CsvStorageProvider(connectionString, typeof(TestData)),
"SQLite" => new DatabaseStorageProvider(dbContext),
"MySQL" => new DatabaseStorageProvider(dbContext),
_ => throw new ArgumentException($"Unsupported storage type: {storageType}")
};
}
public async Task SaveDataAsync(IEnumerable data)
{
await _provider.SaveDataAsync(data);
}
public async Task> QueryDataAsync(string channelId, DateTime? startTime, DateTime? endTime)
{
return await _provider.QueryDataAsync(channelId, startTime, endTime);
}
}
}
appsettings.json
json
{
"Storage": {
"Type": "SQLite",
"ConnectionString": "Data Source=testdata.db"
}
}
DataModule.cs(Autofac 注册)
csharp
using Autofac;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using SemiconductorTestSystem.Data.Interfaces;
using SemiconductorTestSystem.Data.Services;
using SemiconductorTestSystem.Data.DbContexts;
namespace SemiconductorTestSystem.Data
{
public class DataModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType().As().SingleInstance();
builder.Register(c =>
{
var configuration = c.Resolve();
var connectionString = configuration["Storage:ConnectionString"];
var optionsBuilder = new DbContextOptionsBuilder();
optionsBuilder.UseSqlite(connectionString); // 或 UseMySql
return new TestDbContext(optionsBuilder.Options);
}).As().InstancePerLifetimeScope();
}
}
}
说明:
通过配置文件动态选择存储方式(CSV、SQLite、MySQL)。
EF Core 提供统一的数据库操作接口。
三、集成与 UI
硬件驱动和数据存储模块与之前的 UI 模块集成如下:
硬件控制界面:通过 IHardwareService 调用硬件驱动,显示状态和操作。
首页和监控界面:通过 IDataStorageService 查询数据,展示表格和曲线。
日志界面:记录硬件状态变化(通过 StatusChanged 事件)和数据存储操作。
示例:更新硬件控制 ViewModel
在 HardwareControlViewModel.cs 中注入 IHardwareService:
csharp
public class HardwareControlViewModel : BindableBase
{
private readonly IHardwareService _hardwareService;
// ... 其他代码
public HardwareControlViewModel(IHardwareService hardwareService)
{
_hardwareService = hardwareService;
// ... 初始化代码
}
// 示例:初始化硬件
private async void InitializeDeviceAsync()
{
if (SelectedDevice != null)
{
var device = await _hardwareService.GetDeviceAsync(SelectedDevice.DeviceName);
await device.InitializeAsync();
UpdateDeviceStatus(device);
}
}
}
示例:保存数据
在 TestController.cs 中注入 IDataStorageService:
csharp
public class TestController : ITestController
{
private readonly IDataStorageService _dataStorageService;
public TestController(IDataStorageService dataStorageService)
{
_dataStorageService = dataStorageService;
}
public async Task SaveTestDataAsync(List data)
{
await _dataStorageService.SaveDataAsync(data);
}
}
四、测试用例
4.1 硬件驱动测试
csharp
using Moq;
using Xunit;
namespace SemiconductorTestSystem.Tests.Hardware
{
public class TektronixPowerSupplyTests
{
[Fact]
public async Task InitializeAsync_ConnectsSuccessfully()
{
// Arrange
var mockComm = new Mock();
mockComm.Setup(c => c.ConnectAsync()).Returns(Task.CompletedTask);
var powerSupply = new TektronixPowerSupply(mockComm.Object);
// Act
await powerSupply.InitializeAsync();
// Assert
Assert.Equal(DeviceStatus.Idle, powerSupply.Status);
mockComm.Verify(c => c.ConnectAsync(), Times.Once());
}
}
}
4.2 数据存储测试
csharp
using Microsoft.EntityFrameworkCore;
using SemiconductorTestSystem.Data.Models;
using SemiconductorTestSystem.Data.Repositories;
using Xunit;
namespace SemiconductorTestSystem.Tests.Data
{
public class DatabaseStorageProviderTests
{
[Fact]
public async Task SaveDataAsync_SavesCorrectly()
{
// Arrange
var options = new DbContextOptionsBuilder()
.UseInMemoryDatabase("TestDb").Options;
var dbContext = new TestDbContext(options);
var provider = new DatabaseStorageProvider(dbContext);
var data = new List
{
new TestData { ChannelId = "1", Temperature = 25, Voltage = 5 }
};
// Act
await provider.SaveDataAsync(data);
// Assert
Assert.Equal(1, await dbContext.TestDatas.CountAsync());
}
}
}
五、性能优化
硬件驱动:
使用异步操作(async/await)避免阻塞。
缓存通信连接,减少重复初始化。
数据存储:
EF Core 使用批量插入(AddRangeAsync)提高性能。
CSV 存储使用 StreamWriter 异步写入。
多设备支持:
使用 Parallel.ForEachAsync 处理多设备通信。
实现连接池管理 TCP 连接。
六、后续支持
如果需要以下内容,请提供具体需求,我会进一步补充:
Modbus 驱动的完整实现:支持更多寄存器操作。
多设备并发管理:使用 Actor 模型(如 Akka.NET)。
云端存储:集成 Azure Cosmos DB 或 AWS RDS。
更详细的测试用例:覆盖复杂场景。
请确认是否需要调整其他模块(如 UI 或计算模块)或更详细的代码实现,我会继续提供!