gpt4 book ai didi

.Net Thread vs ThreadPool vs SerialPort 通信任务

转载 作者:行者123 更新时间:2023-12-04 20:17:53 25 4
gpt4 key购买 nike

我在使用 SerialPort 的 C# .Net 4.0 应用程序中遇到了一个有趣的问题。类和任一 ThreadPool.QueueUserWorkItemTask s。

仅当我同时使用 2 个或更多 SerialPort 时才会出现此问题。每个串行端口都在我以 3 种方式之一创建的自己的线程中运行:

  • new Thread(DoSerialCommX)
  • ThreadPool.QueueUserWorkItem(DoSerialCommX)
  • new Task(DoSerialCommX, TaskCreationOptions.LongRunning).Start()

  • 为了说明问题,我创建了我的 DoSerialCommX在循环中永远读取和写入串行端口的方法。它看起来像这样:(我实际上并没有在我的真实程序中这样做。这只是我的测试程序中的一个片段,用于隔离和说明问题)。
    private void DoSerialCommX()
    {
    SerialPort port = new SerialPort("ComX", 9600);
    port.Open();

    while(true)
    {
    //Read and write to serial port
    }
    }

    如果我使用方法 2 或 3,串行通信会断断续续,并且我会收到许多通信超时。如果我使用方法1,一切都很好。另外,我应该提到这似乎只发生在我的基于 Intel Atom 的 PC 上。台式电脑似乎没有问题。

    我知道线程池重用线程,默认情况下 Task使用线程池。而且我知道线程池真正用于短期操作。但我尝试使用 TaskCreationOptions.LongRunning ,我认为这会产生一个专用线程而不是使用线程池,但它仍然不起作用。

    所以问题:是什么让 Thread在这种情况下如此特殊?有没有关于 Thread这使它更适合 IO 操作?

    编辑:
    到目前为止的答案似乎假设我正在尝试将 ThreadPool 或 Tasks 用于永无止境的过程。在我的实际应用中,情况并非如此。我只是在上面的代码中使用了一个永无止境的循环来说明这个问题。我真的很想知道为什么 Thread作品和 ThreadPoolTask别。它们在技术上有什么不同会导致串行通信打嗝?

    最佳答案

    从哲学上讲,执行线程的行为方式 1、2 和 3 之间几乎没有区别。它们都共享相同的默认执行优先级,除非您覆盖它 - 从概念上讲,线程调度程序将使用相同的策略来调度它们。他们都会高兴地坐在圈子里旋转。

    我怀疑方法之间更大的区别是:

  • 基础设施成本(线程、内存等)启动以支持 #2 和 #3 的线程池,所有这些都将与您的执行循环竞争时钟时间片。
  • 肌肉较少的 Atom 上的线程上下文切换成本。 Atom 有一个较小的缓存,
    和更短的处理管道。更多正在运行的线程 = 更多的上下文切换、更多的管道转储和降低的指令缓存效率。

  • 从功能的角度来看,使用方法 2 和方法 3 有点滥用 - 您的意图是永远不会退出该方法。这些策略针对原子、有限操作和有些无指导的执行进行了优化,通常适用于 IO 完成端口任务,例如异步网络、磁盘操作等......(也许你的串口代码也有可能?)

    除非您对适应异步 IO 感兴趣,否则我会跳过 2 和 3。专注于线程 - 似乎您想要更细粒度、可预测的执行控制,而无需 Threadpool 带来的基础设施开销。

    关于.Net Thread vs ThreadPool vs SerialPort 通信任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10117166/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com