首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用线程进行外部通信(PC -> RS485设备)

使用线程进行外部通信(PC -> RS485设备)
EN

Stack Overflow用户
提问于 2018-05-01 08:40:42
回答 1查看 129关注 0票数 0

我正在使用NModbus4通过ModbusRTU (RS485)进行通信。我的程序需要不断地从设备中获取数据,该设备经常断开和连接。当设备断开时,我会得到超时异常(可以理解),在此期间,程序是滞后的(浏览表单、按按钮等)。因为它会等待设备响应。

是否可以将Modbus连接移动到单独的线程,以处理与用户界面并行的线程(或者是否有更好的选项)?

如果是这样的话,请用一个简单的例子来帮助我如何与事件相关(我正在通过事件传递设备数据和信息来显示数据)。

样本代码:

代码语言:javascript
运行
复制
    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开始,所以示例代码可能不符合标准约定--对不起。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-01 09:25:18

线程是一个级别太低的原语--我建议尽可能地调查任务,避免使用线程。

在您的情况下,这就是代码的样子。DataManagement.RequestData调用发生在来自线程池的另一个线程上,但是在那之后,您再次进入主线程的上下文,因此您将不必执行任何同步/封送/等等操作。如果ProcessData方法也很慢,那么您可以和DataManagement.RequestData一样-在一个任务上执行它。再一次,不需要同步。

代码语言:javascript
运行
复制
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) { }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50113569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档