Ваше приложение не отвечает, потому что вы выполняете ввод-вывод в потоке диспетчеризации событий. Это блокирует его для выполнения других задач, таких как рисование вашего пользовательского интерфейса, реагирование на события мыши ...
Чтобы выполнить ввод-вывод в пуле потоков, вы можете использовать async / await, например, так ( не проверено! )
// 1. Run the Write - Part on a Threadpool Thread ...
private Task WriteRegAsync( float variable , ModbusClient client )
{
return Task.Run(() => {
client.WriteMultipleRegisters(
2,
ModbusClient.ConvertFloatToRegisters( variable,
ModbusClient.RegisterOrder.HighLow)
);
});
}
// 2. Run the Read-Part on a Threadpool Thread
private Task<string> ReadRegAsync( int address, ModbusClient client )
{
return Task.Run( () => {
return ModbusClient.ConvertRegistersToFloat(
client.ReadHoldingRegisters(address, 2),
ModbusClient.RegisterOrder.HighLow)
.ToString();
});
}
// "async" makes "await" available for use. Since this is an EventHandler, "async void" is ok. (Usually, you make that "async Task")
private async void tmr_Modbus_Com_Tick(object sender, EventArgs e)
{
tmr_Modbus_Com.Enabled = false;
// Write _asynchronously_, your app will stay responsive.
await WriteRegAsync( (float)variable, modbusClient );
// then read asynchronously. Again, App will stay responsive.
textbox1.Text = await ReadRegAsync(384, modbusClient);
tmr_Modbus_Com.Enabled = true
}
Имейте в виду, что это не готовый код производства ! Возможно, что смежные вызовы обработчика событий могут «обогнать» друг друга. Возможно, вы захотите добавить некоторую обработку ошибок, ведение журнала, ...
Еще один момент: если ModbusClient
уже предоставляет асинхронные методы, используйте их вместо этого. В приведенном выше примере более или менее просто используется дополнительный поток для одновременной обработки ввода-вывода с вашим пользовательским интерфейсом.