我正在使用NModbus4通过ModbusRTU (RS485)进行通信。我的程序需要不断地从设备中获取数据,该设备经常断开和连接。当设备断开时,我会得到超时异常(可以理解),在此期间,程序是滞后的(浏览表单、按按钮等)。因为它会等待设备响应。
是否可以将Modbus连接移动到单独的线程,以处理与用户界面并行的线程(或者是否有更好的选项)?
如果是这样的话,请用一个简单的例子来帮助我如何与事件相关(我正在通过事件传递设备数据和信息来显示数据)。
样本代码:
public MainGui()
{
InitializeComponent();
DataTransport DataManagment = new DataTransport(); //DataTransport is a class that handles communication and publishes event 'DataSent'
DataManagment.DataSent += new EventHandler<DataSentArgs>(UnpackData);
}
private void slaveDataReqTimer_Tick(object sender, EventArgs e)
{
//Timer that is responsible for fetching data
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
DataManagment.RequestData();
}).Start();
}
public void UnpackData(object sender, DataSentArgs e)
{
//Doing some stuff when data arrives
}
这段代码的问题是,我不能将事件从新线程传递到当前线程(另外,我不知道线程的方法是否正确)。
我刚刚从C#和.NET开始,所以示例代码可能不符合标准约定--对不起。
发布于 2018-05-01 09:25:18
线程是一个级别太低的原语--我建议尽可能地调查任务,避免使用线程。
在您的情况下,这就是代码的样子。DataManagement.RequestData调用发生在来自线程池的另一个线程上,但是在那之后,您再次进入主线程的上下文,因此您将不必执行任何同步/封送/等等操作。如果ProcessData方法也很慢,那么您可以和DataManagement.RequestData一样-在一个任务上执行它。再一次,不需要同步。
public MainWindow()
{
InitializeComponent();
var cts = new CancellationTokenSource();
Unloaded += delegate { cts.Cancel(); };
ProcessData(cts.Token);
}
async void ProcessData(CancellationToken ct)
{
try
{
while (true)
{
ct.ThrowIfCancellationRequested();
try
{
var dataItem = await Task.Run(() => DataManagement.RequestData());
ProcessData(dataItem);
}
catch(Exception_Thrown_By_RequestData e)
{
// decide what do - either break the loop or continue if
// this is not a heavy faiulre
}
await Task.Delay(DelayTime, ct);
}
}
catch (TaskCanceledException) { }
catch (OperationCanceledException) { }
}
https://stackoverflow.com/questions/50113569
复制相似问题