WPF,C#,串行端口通信

WPF,C#,串行端口通信,c#,wpf,serial-port,C#,Wpf,Serial Port,我使用串行端口通信,串行端口有一个DataReceived事件,如果接收数据的页眉和页脚匹配,我将执行2个复杂而冗长的函数,这里我使用循环缓冲区进行数据接收 在两个函数中,第一个函数更新画布上2058字节的图形(面积图),第二个函数对2058字节进行一些复杂的计算。我每3秒接收一次这2058字节 所以我的要求是,当我在另一端的缓冲区中填充数据时,我需要对已经在缓冲区中的数据执行这两个函数(因为它是循环缓冲区,它包含以前填充的数据) 我在这里有点困惑,如何实现这种并发性。我知道一些方法 使用“任务

我使用串行端口通信,串行端口有一个
DataReceived
事件,如果接收数据的页眉和页脚匹配,我将执行2个复杂而冗长的函数,这里我使用循环缓冲区进行数据接收

在两个函数中,第一个函数更新画布上2058字节的图形(面积图),第二个函数对2058字节进行一些复杂的计算。我每3秒接收一次这2058字节

所以我的要求是,当我在另一端的缓冲区中填充数据时,我需要对已经在缓冲区中的数据执行这两个函数(因为它是循环缓冲区,它包含以前填充的数据)

我在这里有点困惑,如何实现这种并发性。我知道一些方法

  • 使用“任务”
  • 使用“线程”
  • 使用“异步&等待”
  • 使用“任务并行库”
  • 使用“后台工作人员”
  • 使用“Dispatcher.Invoke()”
  • 目前我使用的是
    Dispatcher.Invoke()
    ,这会花费太多时间进行UI更新。所以这里发生了时滞


    请告诉我哪种方法更具响应性。

    对于复杂的工作,您可以使用1-5(因为它们适用于此场景)。您可以使用6将结果注入到图形中,因为Dispatcher.Invoke的目的是在UI线程中处理工作,并且是大多数控件所必需的


    我希望这会有所帮助。

    从要完成的工作量来看,由于这是每三秒发生一次,我相信任务和线程池上的排队工作是最好的解决方案

    我不建议生成一个新的专用线程


    根据这个过程需要多长时间和您的配置,我认为您可以考虑在循环中运行少量的永久线程,并查询新接收的数据队列以进行处理(即创建自己的线程池)。这可以通过使用ConcurrentQueue发布和接收数据来实现。此外,您还可以考虑在多线程环境中,在需要低延迟和高性能的情况下,哪种方法会有很大帮助。无论采用哪种解决方案,您都可以从调查中获益。

    我已通过计时器和后台工作同步成功地管理了它

    我注意到的唯一重要的一点是,您需要一个好的处理器,至少是“core-i3”

    Skleanthu先生提出的解决办法也是可以接受的。谢谢

    谢谢安德烈亚斯·穆勒先生,是的,我明白你的意思


    非常感谢大家。

    为什么不在读取新数据之前复制一份缓冲区,然后在此基础上构建图表呢?是的,除了4和6之外的所有内容。您可以在线程上运行“复杂函数”,而不是图形更新。您可以在
    datareceived
    事件中正确执行所有操作。它在新线程中运行(当从SerialPort对象接收数据时,在辅助线程上引发DataReceived事件-),这将是转换图形数据、调用图形和启动复杂处理的理想场所。考虑先从循环缓冲区复制数据。如果您可以保证,在下一个数据到达之前,复杂的处理完成了什么,那么您甚至可以使用
    static
    buffer来实现这一点。+1用于数据流。在UI线程上运行的数据流末尾粘贴一个
    ActionBlock
    (使用
    TaskScheduler.FromCurrentSynchronizationContext
    ).我认为,
    BufferBlock
    会像你建议的那样有用,因为它可以有多个消息输入目标和单个消息接收目标,这在OP的情况下似乎是合适的。我认为这取决于具体情况。显然,在可维护性和对未来更改的支持方面,最好的选择是最终使用带有ActionBlock的BufferBlock或专用线程池来处理消息。但是,如果约束是一成不变的(每3秒一条消息,处理时间不会太长),生成任务将更容易,也可能更容易阅读。