I have a CommanderForm which may open and close TCP connection and open ECTStatePageForm. I want that if TCP connection is established then after open ECTStatePageForm it starts automatically update data, if TCP connection closes or lost then it stops update data and if tcp connection reopened or resumed then it again starts automatically receive data.

In my current implementation ECTStagePageForm dont automatically start updating data.

using ModBusHelper;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CommonFunctions;
using static ModBusHelper.ModBusExporterLinker;
using static ModBusHelper.ModBusCommands;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Xml.Linq;
using NModbus.Device;
using System.Net.Sockets;
using SharpPcap.LibPcap;
using SharpPcap;
using Microsoft.Win32;
using NModbus;
using NModbus.Message;
using System.Net.Http;
using System.Net;

namespace Configurator
{
    public partial class CommanderForm : Form
    {
        ModBusCommands CommandsHelper = new ModBusCommands();
        ModBusFunctions ModbusFunctionsHelper = new ModBusFunctions();
        ModBusExporterLinker ExporterLinkerHelper = new ModBusExporterLinker();

        private Tuple<TcpClient, IModbusMaster> _connection;
        private Timer connectionCheckTimer;

        private static CommanderForm commanderFormInstance;
        public static CommanderForm FormInstance;

        private static ECTStatePageForm ectStatePageFormInstance;
        private static SWRCTStatePageForm swrctStatePageFormInstance;
        private static JournalRecordForm journalRecordFormInstance;

        // Define events for connection management
        public event Action<Tuple<TcpClient, IModbusMaster>> ConnectionStarted;
        public event Action ConnectionStopped;

        public CommanderForm()
        {
            InitializeComponent();
            FormInstance = this;

            // Initialize connection check timer
            connectionCheckTimer = new Timer();
            connectionCheckTimer.Interval = 1000; // Check every second
            connectionCheckTimer.Tick += ConnectionCheckTimer_Tick;

            CurrentConnectionStateTextBox.Text = "Отключено";
            CurrentConnectionStateTextBox.ForeColor = Color.Red;
        }

        public static CommanderForm GetInstance()
        {
            if (commanderFormInstance == null || commanderFormInstance.IsDisposed)
            {
                commanderFormInstance = new CommanderForm();
            }
            return commanderFormInstance;
        }

        public Tuple<TcpClient, IModbusMaster> GetCurrentConnection()
        {
            return _connection;
        }

        private void ConnectionStartButton_Click(object sender, EventArgs e)
        {
            int modBusPort;
            string boardIP;

            if (BoardIPTextBox.Text != "")
            {
                boardIP = BoardIPTextBox.Text;
            }
            else
            {
                MessageBox.Show("Введите IP адрес устройства.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Attempt to retrieve and parse the ModBus port
            try
            {
                modBusPort = int.Parse(ModBusPortTextBox.Text);
            }
            catch (FormatException)
            {
                MessageBox.Show("Неправильный формат номера порта. Пожалуйста введите целое число.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            catch (ArgumentNullException)
            {
                MessageBox.Show("Введите номер порта ModBus.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            CurrentConnectionStateTextBox.ForeColor = Color.DarkGray;
            CurrentConnectionStateTextBox.Text = "Подключение...";

            try
            {
                _connection = ConnectionManager.OpenConnection(boardIP, modBusPort);

                // Trigger the ConnectionStarted event
                ConnectionStarted?.Invoke(_connection);

                CurrentConnectionStateTextBox.Text = "Подключено";
                CurrentConnectionStateTextBox.ForeColor = Color.Green;
                // Start the connection check timer
                connectionCheckTimer.Start();
            }
            catch (ArgumentException ex)
            {
                CurrentConnectionStateTextBox.ForeColor = Color.Red;
                CurrentConnectionStateTextBox.Text = "Ошибка";
                MessageBox.Show("Ошибка ввода: " + ex.Message);
                return;
            }
            catch (InvalidOperationException ex)
            {
                CurrentConnectionStateTextBox.ForeColor = Color.Red;
                CurrentConnectionStateTextBox.Text = "Ошибка";
                MessageBox.Show("Ошибка соединения: " + ex.Message);
                return;
            }
        }

        private void ConnectionStopButton_Click(object sender, EventArgs e)
        {
            try
            {
                if (ConnectionManager.IsConnectionActive())
                {
                    ConnectionManager.CloseConnection();

                    // Trigger the ConnectionStopped event
                    ConnectionStopped?.Invoke();

                    CurrentConnectionStateTextBox.Text = "Отключено";
                    CurrentConnectionStateTextBox.ForeColor = Color.Red;
                }
                connectionCheckTimer.Stop();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ошибка при отключении: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void ConnectionCheckTimer_Tick(object sender, EventArgs e)
        {
            if (_connection != null && _connection.Item1.Connected)
            {
                UpdateConnectionStateTextBox("Подключено", Color.Green);
            }
            else
            {
                UpdateConnectionStateTextBox("Отключено", Color.Red);
                if (_connection != null && !_connection.Item1.Connected)
                {
                    ConnectionStopped?.Invoke();
                }
            }
        }

        private void UpdateConnectionStateTextBox(string state, Color color)
        {
            if (CurrentConnectionStateTextBox.InvokeRequired)
            {
                CurrentConnectionStateTextBox.Invoke(new Action(() =>
                {
                    CurrentConnectionStateTextBox.Text = state;
                    CurrentConnectionStateTextBox.ForeColor = color;
                }));
            }
            else
            {
                CurrentConnectionStateTextBox.Text = state;
                CurrentConnectionStateTextBox.ForeColor = color;
            }
        }

        private void WriteValuesButton_Click(object sender, EventArgs e)
        {
            bool adminRights = false;

            try
            {
                // Check for admin rights
                try
                {
                    if ((LoginComboBox.SelectedItem.ToString() == "Администратор") && (PasswordTextBox.Text == "admin"))
                    {
                        adminRights = true;
                    }
                }
                catch (NullReferenceException)
                {
                    MessageBox.Show("Выберите тип пользователя.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                // Ensure settings are not empty
                if ((Database.GeneralSettings_TextFormat.cmns.nAchans != "") && (Database.GeneralSettings_TextFormat.cmns.nDiap != ""))
                {
                    try
                    {
                        ExporterLinkerHelper.WriteSettings(Database.GeneralSettings_TextFormat, adminRights, _connection);
                        write_SettingsTextBox.ForeColor = Color.Green;
                        write_SettingsTextBox.Text = "ОК";
                    }
                    catch (Exception ex)
                    {
                        write_SettingsTextBox.ForeColor = Color.Red;
                        write_SettingsTextBox.Text = "Ошибка";
                        MessageBox.Show($"При записи параметров возникла ошибка: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }
                else
                {
                    write_SettingsTextBox.ForeColor = Color.Red;
                    write_SettingsTextBox.Text = "Ошибка";
                    MessageBox.Show("Не указаны параметры для записи. Пожалуйста, проверьте конфигурацию.", "Предупреждение", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }
            catch (Exception ex)
            {
                write_SettingsTextBox.ForeColor = Color.Red;
                write_SettingsTextBox.Text = "Ошибка";
                MessageBox.Show($"Ошибка: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

        private void ReadValuesButton_Click(object sender, EventArgs e)
        {
            try
            {
                // Attempt to read general settings
                try
                {
                    Database.GeneralSettings_TextFormat = ExporterLinkerHelper.get_GeneralSettings_Text(_connection);
                    read_SettingsTextBox.ForeColor = Color.Green;
                    read_SettingsTextBox.Text = "ОК";
                }
                catch (Exception ex)
                {
                    read_SettingsTextBox.ForeColor = Color.Red;
                    read_SettingsTextBox.Text = "Ошибка";
                    MessageBox.Show($"При чтении параметров возникла ошибка: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
            catch (Exception ex)
            {
                read_SettingsTextBox.ForeColor = Color.Red;
                read_SettingsTextBox.Text = "Ошибка";
                MessageBox.Show($"Ошибка: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

        private void upload_firmware_defaultButton_Click(object sender, EventArgs e)
        {
            try
            {
                int groupsIdentificatorsAccumulator = 0x00;
                int cmnsIdentificator = 0x01;
                int netsIdentificator = 0x02;
                int timeIdentificator = 0x04;
                int synsIdentificator = 0x08;
                int swrcsIdentificator = 0x10;
                int measIdentificator = 0x20;

                if (upload_firmware_CheckBox1.Checked)
                {
                    groupsIdentificatorsAccumulator |= cmnsIdentificator;
                }
                if (upload_firmware_CheckBox2.Checked)
                {
                    groupsIdentificatorsAccumulator |= netsIdentificator;
                }
                if (upload_firmware_CheckBox3.Checked)
                {
                    groupsIdentificatorsAccumulator |= timeIdentificator;
                }
                if (upload_firmware_CheckBox4.Checked)
                {
                    groupsIdentificatorsAccumulator |= synsIdentificator;
                }
                if (upload_firmware_CheckBox5.Checked)
                {
                    groupsIdentificatorsAccumulator |= swrcsIdentificator;
                }
                if (upload_firmware_CheckBox6.Checked)
                {
                    groupsIdentificatorsAccumulator |= measIdentificator;
                }

                ushort bitMask = Convert.ToUInt16(groupsIdentificatorsAccumulator);

                upload_firmware_defaultTextBox1.Text = $"0x{bitMask.ToString("X2")}";

                try
                {
                    WriteSingleRegisterRequestResponse response = CommandsHelper.upload_firmware_default(_connection.Item2, bitMask);
                    if ($"0x{response.Data[0].ToString("X2")}" == $"0x{bitMask.ToString("X2")}")
                    {
                        upload_firmware_defaultTextBox2.ForeColor = Color.Green;
                        upload_firmware_defaultTextBox2.Text = "ОК";
                    }
                    else
                    {
                        upload_firmware_defaultTextBox2.ForeColor = Color.Red;
                        upload_firmware_defaultTextBox2.Text = "Ошибка";
                    }
                }
                catch (Exception modbusException)
                {
                    upload_firmware_defaultTextBox2.ForeColor = Color.Red;
                    upload_firmware_defaultTextBox2.Text = "Ошибка";
                    MessageBox.Show($"Ошибка при загрузке параметров: {modbusException.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
            catch (Exception ex)
            {
                upload_firmware_defaultTextBox2.ForeColor = Color.Red;
                upload_firmware_defaultTextBox2.Text = "Ошибка";
                MessageBox.Show($"Ошибка: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

        private void upload_settingsButton_Click(object sender, EventArgs e)
        {
            try
            {
                WriteSingleRegisterRequestResponse response = CommandsHelper.upload_settings(_connection.Item2, 0x00);
                if (response.Data[0] == 0)
                {
                    try
                    {
                        if (upload_settingsCheckBox.Checked)
                        {
                            WriteSingleRegisterRequestResponse responseReset = CommandsHelper.reset_ect(_connection.Item2);
                            if ($"0x{responseReset.Data[0].ToString("X4")}" == "0x00FF")
                            {
                                upload_settingsTextBox.ForeColor = Color.Green;
                                upload_settingsTextBox.Text = "ОК";
                            }
                        }
                        else
                        {
                            upload_settingsTextBox.ForeColor = Color.Red;
                            upload_settingsTextBox.Text = "Ошибка";
                        }
                    }
                    catch (Exception modbusException)
                    {
                        upload_settingsTextBox.ForeColor = Color.Red;
                        upload_settingsTextBox.Text = "Ошибка";
                        MessageBox.Show($"Ошибка при загрузке параметров: {modbusException.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }
            }
            catch (Exception ex)
            {
                upload_settingsTextBox.ForeColor = Color.Red;
                upload_settingsTextBox.Text = "Ошибка";
                MessageBox.Show($"Ошибка при загрузке параметров: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

        private void get_last_settings_recordButton_Click(object sender, EventArgs e)
        {
            // Perform Modbus operation
            bool[] lastSettingsRecordBoolArray;
            byte lastSettingsRecord;
            try
            {
                lastSettingsRecordBoolArray = CommandsHelper.get_last_settings_record(_connection.Item2);
                lastSettingsRecord = ModbusFunctionsHelper.ConvertBoolArrayToByte(lastSettingsRecordBoolArray);
                if ($"0x{lastSettingsRecord.ToString("X2")}" == "0x00")
                {
                    get_last_settings_recordTextBox.ForeColor = Color.Green;
                    get_last_settings_recordTextBox.Text = "ОК";
                }
                else
                {
                    get_last_settings_recordTextBox.ForeColor = Color.Red;
                    get_last_settings_recordTextBox.Text = "Ошибка";
                }
            }
            catch (Exception ex)
            {
                get_last_settings_recordTextBox.ForeColor = Color.Red;
                get_last_settings_recordTextBox.Text = "Ошибка";
                MessageBox.Show($"Ошибка получения статуса последней записи настроек: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

        private void reset_ectButton_Click(object sender, EventArgs e)
        {
            // Perform Modbus operation to reset ect
            try
            {
                WriteSingleRegisterRequestResponse response = CommandsHelper.reset_ect(_connection.Item2);
                if ($"0x{response.Data[0].ToString("X4")}" == "0x00FF")
                {
                    reset_ectTextBox.ForeColor = Color.Green;
                    reset_ectTextBox.Text = "ОК";
                }
                else
                {
                    reset_ectTextBox.ForeColor = Color.Red;
                    reset_ectTextBox.Text = "Ошибка";
                }
            }
            catch (Exception ex)
            {
                reset_ectTextBox.ForeColor = Color.Red;
                reset_ectTextBox.Text = "Ошибка";
                MessageBox.Show($"Ошибка перезагрузки ЭТТ: {ex.Message}", "Ошибка ModBus соединения", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

        private void nulify_swrcButton_Click(object sender, EventArgs e)
        {
            bool adminRights = false;

            try
            {
                // Try to determine if the user has admin rights
                try
                {
                    if ((LoginComboBox.SelectedItem?.ToString() == "Администратор") && (PasswordTextBox.Text == "admin"))
                    {
                        adminRights = true;
                    }
                }
                catch (NullReferenceException)
                {
                    nulify_swrcTextBox.ForeColor = Color.Red;
                    nulify_swrcTextBox.Text = "Ошибка";
                    MessageBox.Show("Выберите тип пользователя.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (adminRights)
                {
                    try
                    {
                        // Perform Modbus operation
                        WriteSingleRegisterRequestResponse response = CommandsHelper.nulify_swrc(_connection.Item2);
                        if ($"0x{response.Data[0].ToString("X4")}" == "0x00FF")
                        {
                            nulify_swrcTextBox.ForeColor = Color.Green;
                            nulify_swrcTextBox.Text = "ОК";
                        }
                        else
                        {
                            nulify_swrcTextBox.ForeColor = Color.Red;
                            nulify_swrcTextBox.Text = "Ошибка";
                        }
                    }
                    catch (Exception modbusException)
                    {
                        nulify_swrcTextBox.ForeColor = Color.Red;
                        nulify_swrcTextBox.Text = "Ошибка";
                        MessageBox.Show($"При обнулении данных расхода ресурса произошла ошибка: {modbusException.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }
                else
                {
                    nulify_swrcTextBox.ForeColor = Color.Red;
                    nulify_swrcTextBox.Text = "Ошибка";
                    MessageBox.Show("Для выполнения команды требуются права Администратора.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }
            catch (Exception ex)
            {
                nulify_swrcTextBox.ForeColor = Color.Red;
                nulify_swrcTextBox.Text = "Ошибка";
                MessageBox.Show($"Ошибка: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

        private void clear_swrc_journalButton_Click(object sender, EventArgs e)
        {
            bool adminRights = false;

            try
            {
                // Determine if the user has admin rights
                try
                {
                    if ((LoginComboBox.SelectedItem?.ToString() == "Администратор") && (PasswordTextBox.Text == "admin"))
                    {
                        adminRights = true;
                    }
                }
                catch (NullReferenceException)
                {
                    MessageBox.Show("Выберите тип пользователя.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (adminRights)
                {
                    try
                    {
                        bool clearJournal = clear_swrc_journalCheckBox.Checked;
                        WriteSingleRegisterRequestResponse response = CommandsHelper.clear_swrc_journal(_connection.Item2, clearJournal);

                        string checkString = "0x00";
                        if (clearJournal)
                        {
                            checkString = "0x01";
                        }

                        if ($"0x{response.Data[0].ToString("X2")}" == checkString)
                        {
                            clear_swrc_journalTextBox.ForeColor = Color.Green;
                            clear_swrc_journalTextBox.Text = "ОК";
                        }
                        else
                        {
                            clear_swrc_journalTextBox.ForeColor = Color.Red;
                            clear_swrc_journalTextBox.Text = "Ошибка";
                        }
                    }
                    catch (Exception modbusEx)
                    {
                        clear_swrc_journalTextBox.ForeColor = Color.Red;
                        clear_swrc_journalTextBox.Text = "Ошибка";
                        MessageBox.Show($"Ошибка при очистке журнала СКРВ: {modbusEx.Message}", "Ошибка ModBus соединения", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }
                else
                {
                    clear_swrc_journalTextBox.ForeColor = Color.Red;
                    clear_swrc_journalTextBox.Text = "Ошибка";
                    MessageBox.Show("Для выполнения команды требуются права Администратора.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }
            catch (Exception ex)
            {
                clear_swrc_journalTextBox.ForeColor = Color.Red;
                clear_swrc_journalTextBox.Text = "Ошибка";
                MessageBox.Show($"Ошибка: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

        private void ECTStatePageButton_Click(object sender, EventArgs e)
        {
            // Check if an instance is already open or disposed
            if (ectStatePageFormInstance == null || ectStatePageFormInstance.IsDisposed)
            {
                // Create and show a new instance
                ectStatePageFormInstance = new ECTStatePageForm(FormInstance);
                ectStatePageFormInstance.Show();
            }
            else
            {
                // If instance exists, bring it to the front
                ectStatePageFormInstance.BringToFront();
                ectStatePageFormInstance.Focus();
            }
        }

        private void SWRCTStatePageButton_Click(object sender, EventArgs e)
        {
            // Check if an instance is already open or disposed
            if (swrctStatePageFormInstance == null || ectStatePageFormInstance.IsDisposed)
            {
                // Create and show a new instance
                swrctStatePageFormInstance = new SWRCTStatePageForm(FormInstance);
                swrctStatePageFormInstance.Show();
            }
            else
            {
                // If instance exists, bring it to the front
                swrctStatePageFormInstance.BringToFront();
                swrctStatePageFormInstance.Focus();
            }
        }

        private void ReadJournalButton_Click(object sender, EventArgs e)
        {
            // Check if an instance is already open or disposed
            if (journalRecordFormInstance == null || journalRecordFormInstance.IsDisposed)
            {
                // Create and show a new instance
                journalRecordFormInstance = new JournalRecordForm(FormInstance, Database.Filtered_Journal_Records, _connection);
                journalRecordFormInstance.Show();
            }
            else
            {
                // If instance exists, bring it to the front
                journalRecordFormInstance.BringToFront();
                journalRecordFormInstance.Focus();
            }
        }
    }
}

using NModbus.Device;
using ModBusHelper;
using System;
using System.Data;
using System.Drawing;
using System.Net.Sockets;
using System.Windows.Forms;
using NModbus;
using System.ComponentModel;

namespace Configurator
{
    public partial class ECTStatePageForm : Form
    {
        CommanderForm CommanderForm;
        private BackgroundWorker BackgroundWork = new BackgroundWorker();
        private Timer connectionCheckTimer = new Timer();

        DataTable rmsDataTable = new DataTable();
        DataTable diapsDataTable = new DataTable();

        ModBusProfile ModBusProfileHelper = new ModBusProfile();
        ModBusExporterLinker ExporterLinkerHelper = new ModBusExporterLinker();

        private Tuple<TcpClient, IModbusMaster> _connection;

        public ECTStatePageForm(CommanderForm CommanderFormInstance)
        {
            InitializeComponent();
            this.CommanderForm = CommanderFormInstance;

            // Subscribe to events from the CommanderForm
            CommanderForm.ConnectionStarted += OnConnectionStarted;
            CommanderForm.ConnectionStopped += OnConnectionStopped;

            ModBusProfile.esp esp = ExporterLinkerHelper.esp_Default;

            ste1TextBox.Text = esp.ste[0].ToString();
            ste2TextBox.Text = esp.ste[1].ToString();
            ste3TextBox.Text = esp.ste[2].ToString();
            ste4TextBox.Text = esp.ste[3].ToString();

            rmsDataTable.Columns.Add("Канал", typeof(int));
            rmsDataTable.Columns.Add("Действующее значение тока", typeof(float));
            rmsDataTable.Rows.Add(new object[] { 0, esp.rms[0] });
            rmsDataGridView.DataSource = rmsDataTable;

            diapsDataTable.Columns.Add("Канал", typeof(int));
            diapsDataTable.Columns.Add("Значения диапазонов", typeof(sbyte));
            diapsDataTable.Rows.Add(new object[] { 0, esp.diaps[0] });
            diapsDataGridView.DataSource = diapsDataTable;

            BackgroundWork.WorkerSupportsCancellation = true;
            BackgroundWork.DoWork += new DoWorkEventHandler(BackgroundWork_DoWork);
        }

        private void OnConnectionStarted(Tuple<TcpClient, IModbusMaster> connection)
        {
            _connection = connection;
            if (!BackgroundWork.IsBusy)
            {
                BackgroundWork.RunWorkerAsync(argument: _connection);
            }
        }

        private void OnConnectionStopped()
        {
            if (BackgroundWork.IsBusy)
            {
                BackgroundWork.CancelAsync();
            }
        }

        private void BackgroundWork_DoWork(object sender, DoWorkEventArgs e)
        {
            var connection = e.Argument as Tuple<TcpClient, IModbusMaster>;
            if (connection == null)
            {
                Invoke(new Action(() =>
                    MessageBox.Show("Ошибка соединения", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error)
                ));
                return;
            }

            TcpClient tcpClient = connection.Item1;
            IModbusMaster modbusMaster = connection.Item2;

            while (!e.Cancel)
            {
                if ((sender as BackgroundWorker).CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }

                if (!tcpClient.Connected)
                {
                    Invoke(new Action(() =>
                        MessageBox.Show("Соединение потеряно", "Ошибка соединения", MessageBoxButtons.OK, MessageBoxIcon.Warning)
                    ));
                    break;
                }

                try
                {
                    ModBusProfile.esp espValues = ModBusProfileHelper.ect_state_page_Read(modbusMaster);

                    Invoke(new Action(() =>
                    {
                        ste1TextBox.Text = espValues.ste[0].ToString();
                        ste2TextBox.Text = espValues.ste[1].ToString();
                        ste3TextBox.Text = espValues.ste[2].ToString();
                        ste4TextBox.Text = espValues.ste[3].ToString();

                        UpdateDataGrid(rmsDataGridView, rmsDataTable, espValues.rms);
                        UpdateDataGrid(diapsDataGridView, diapsDataTable, espValues.diaps);
                    }));

                    System.Threading.Thread.Sleep(1000);
                }
                catch (Exception ex)
                {
                    Invoke(new Action(() =>
                        MessageBox.Show($"Ошибка Modbus соединения: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error)
                    ));
                    break;
                }
            }
        }

        private void UpdateDataGrid<T>(DataGridView gridView, DataTable table, T[] values)
        {
            gridView.Invoke(new MethodInvoker(() =>
            {
                while (values.Length > table.Rows.Count)
                {
                    table.Rows.Add(new object[] { table.Rows.Count, default(T) });
                }
                while (values.Length < table.Rows.Count)
                {
                    table.Rows.RemoveAt(table.Rows.Count - 1);
                }

                for (int i = 0; i < values.Length; i++)
                {
                    table.Rows[i][1] = values[i];
                }

                gridView.DataSource = table;
            }));
        }

        private void ECTStatePageForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (BackgroundWork.WorkerSupportsCancellation)
            {
                BackgroundWork.CancelAsync();
            }

            CommanderForm.ConnectionStarted -= OnConnectionStarted;
            CommanderForm.ConnectionStopped -= OnConnectionStopped;
        }
    }
}