You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于EasyModbusTCP的PLC数据拉取服务MVVM集成咨询

WPF MVVM模式下集成异步Modbus服务的问题

我是编程新手,仅学习编程数月,已使用EasyModbusTCP库开发出可正常运行的WPF程序,且实现了Modbus异步读取以避免界面冻结。现需扩展该程序,从Modbus拉取600余个线圈和寄存器的数据,同时借助CommunityToolkit迁移至MVVM模式,但不清楚如何在ViewModel中创建相关服务,对此感到困惑。以下为简化后的相关代码示例:

ConductivityView XAML代码

<ItemsControl Grid.Row="2" ItemsSource="{Binding ConductivityTanks}">
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="{x:Type vm:ConductivityGridElementViewModel}">
            <controls:ConductivityGridElement DataContext="{Binding}"></controls:ConductivityGridElement>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

CodeBehind代码

public partial class BConductivityView : UserControl
{
    ConductivityViewModel conductivityViewModel;
    public BConductivityView()
    {
        InitializeComponent();
        conductivityViewModel = new ConductivityViewModel();
        this.DataContext = conductivityViewModel;
    }
}

需要集成Modbus服务的ConductivityViewModel代码

public partial class ConductivityViewModel : ObservableObject
{ 
    [ObservableProperty]
    private ObservableCollection<ConductivityGridElementViewModel> _conductivityTanks;

    public ConductivityViewModel()
    {
        _conductivityTanks = new ObservableCollection<ConductivityGridElementViewModel>();

        ConductivityTanks.Clear();
        //添加初始模拟数据用于显示
        for (int i = 0; i <= 32; i++)
        {
            ConductivityTanks.Add(new ConductivityGridElementViewModel
            {
                Id = i.ToString(),
                Use = true,
                TankNo = i.ToString(),
                Sp = (1000 + i).ToString(),
                Pv = (1500 + i).ToString(),
                Valve = false,
                TimeLeft = (4 + i).ToString(),
                Timer = (5).ToString(),
                SensorMinimum = "0",
                SensorMaximum = "10000",
                Raw = "1670"
            });
        }

        public void ModbusReadAsync()
        {
             // 发起异步调用启动Modbus拉取,并更新ConductivityTanks中的所有ConductivityGridElement
        }
    }
}

当前的Modbus服务类代码

public static class ModbusService
{
    public static CancellationTokenSource cts = new CancellationTokenSource();
    public static ModbusClient MB = new ModbusClient();
    private static bool[] coils1 = new bool[120];
    private static bool[] coils2 = new bool[40];
    private static int[] registers1 = new int[121];
    private static int[] registers2 = new int[121];
    private static int[] registers3 = new int[121];

    public static void ConnectToPLC(string IP, int Port, bool ReConnect)
    {
        cts.Cancel();
        ConnectionExist = false;
        MB.Disconnect();
        MB = new ModbusClient(IP, Port);
        try
        {
            MB.Connect();
            ConnectionExist = true;
            ReadPLCAsync();
        }
        catch (Exception)
        {
            MessageBox.Show("连接错误。\n不读取PLC直接启动。");
        }
    }

    public static async void ReadPLCAsync()
    {
        await Task.Run(async () =>
        {
            await Read(cts.Token);
        });
    }


    private static async Task<bool> Read(CancellationToken cancellationToken)
    {
        while (ConnectionExist)
        {
            try
            {
                coils1 = MB.ReadCoils(0, 120);
                coils2 = MB.ReadCoils(121, 40);

                registers1 = MB.ReadHoldingRegisters(0, 122);
                registers2 = MB.ReadHoldingRegisters(122, 122);
                registers3 = MB.ReadHoldingRegisters(244, 122);

                General.CPUinRUN = coils1[0];
                General.ValveON = coils1[1];
                General.SDCardEject = coils1[2];
                General.SDCardEject = coils1[3];
                Conductivity.MasterON = coils1[4];
                Fresh.MasterON = coils1[5];
                Level.MasterON = coils1[6];
                General.SendEmail = coils1[7];

                Array.Copy(coils1, 8, Conductivity.Valve, 0, 32);
                Array.Copy(coils1, 40, Conductivity.CValveMan, 0, 32);

                Array.Copy(coils1, 72, Fresh.FValve, 0, 32);
                Fresh.RunOnSaturday = coils1[104];
                Fresh.RunOnSunday = coils1[105];
                Fresh.RunOnWeekend = coils1[106];

                Array.Copy(coils1, 107, Level.L_Alarm, 0, 10);
                Array.Copy(coils1, 117, Level.L_AlarmOFF, 0, 5);
                Array.Copy(coils2, 0, Level.L_AlarmOFF, 5, 5);
                Array.Copy(coils2, 5, Level.L_Filling, 0, 10);
                Array.Copy(coils2, 15, Level.L_InRange, 0, 10);
                Array.Copy(coils2, 25, Level.L_Valve, 0, 10);

                Conductivity.ON = coils2[35];
                Fresh.ON = coils2[36];
                Level.ON = coils2[37];
            }
            catch (ConnectionException)
            {
                ConnectionExist = false;
                MBC.MB.Disconnect();
                MessageBox.Show("从MBC类读取PLC时出现问题。");

            }
            await Task.Delay(1000);
        }
        return true;

    }

}

应用程序整体界面

应用界面

内容的提问来源于stack exchange,提问作者Evgeniy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 15:30:55