.NET线程VS线程池VS任务进行的SerialPort通讯 [英] .Net Thread vs ThreadPool vs Task for SerialPort Communication

查看:140
本文介绍了.NET线程VS线程池VS任务进行的SerialPort通讯的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的C#.NET使用的SerialPort 类和4.0应用程序或者 ThreadPool.QueueUserWorkItem 工作秒。

I've run into an interesting problem in my C# .Net 4.0 application using the SerialPort class and either ThreadPool.QueueUserWorkItem or Tasks.

如果我同时使用2个或更多SerialPorts只出现问题。每个串口在自己的线程上运行,我在1 3的方式创建:

The problem only occurs if I use 2 or more SerialPorts simultaneously. Each serial port runs in its own thread that I create in 1 of 3 ways:

  1. 新的Thread(DoSerialCommX)
  2. ThreadPool.QueueUserWorkItem(DoSerialCommX)
  3. 新建任务(DoSerialCommX,TaskCreationOptions.LongRunning)。开始()
  1. new Thread(DoSerialCommX)
  2. ThreadPool.QueueUserWorkItem(DoSerialCommX)
  3. new Task(DoSerialCommX, TaskCreationOptions.LongRunning).Start()

要说明这个问题,我创建了我的 DoSerialCommX 方法来读取,并在循环中写入到串行端口,直到永远。它看起来像这样的东西。(我不是真正做这在我的真正的程序这仅仅是一个片段从我的测试程序,它隔离并说明了这个问题)

To illustrate the problem, I created my DoSerialCommX method to read and write to the serial port forever in a loop. It looks something like this: (I'm not actually doing this in my real program. This is just a snippet from my test program that isolates and illustrates the problem).

private void DoSerialCommX()
{
    SerialPort port = new SerialPort("ComX", 9600);
    port.Open();

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

如果我使用这两种方法2或3,串行通讯时断时续,我收到许多通信超时。如果我使用方法1,一切都很好。另外,我应该提到这似乎只发生在我的英特尔凌动的个人电脑。台式电脑似乎也没有问题。

If I use either method 2 or 3, the serial communication stutters and I receive many communication timeouts. If I use method 1, all is good. Also, I should mention this only seems to occur on my Intel Atom based PCs. Desktop PC's seem to have no problems.

我知道线程池重用线程,默认情况下工作使用线程池。而且我知道,线程池真的打算为短期操作。不过,我尝试使用 TaskCreationOptions.LongRunning ,我认为会产生一个专门的线程,而不是使用线程池,但它仍然没有奏效。

I know the thread pool reuses threads, and by default Task uses the thread pool. And I know that the thread pool really intended for short-lived operations. But I tried using the TaskCreationOptions.LongRunning, which I thought would spawn a dedicated thread rather than use the thread pool, but it still didn't work.

所以这个问题:是什么让所以在这种情况下,特别?是否有一些关于,使得它更适合的IO操作?

So the Question: What makes Thread so special in this situation? Is there something about Thread that makes it better suited for IO operations?

编辑: 这些问题的答案似乎很远的假设,我想使用线程池或任务的一个永无止境的过程。在我的实际应用,这是不是这样的。我只使用在code永无止境的循环上面来说明问题。我真的需要知道为什么作品和线程池工作没有。什么是对他们在技术上的不同会导致串行通信打​​嗝?

The answers so far seem to assume that I am trying to use the ThreadPool or Tasks for a never-ending process. In my real application this is not the case. I'm only using a never-ending loop in the code above to illustrate the problem. I really need to know why Thread works and ThreadPool and Task don't. What is technically different about them that would cause the serial communication to hiccup?

推荐答案

从哲学的存在是如何执行的线程行为1,2和3之间的差别不大。他们都有着相同的默认执行优先级,除非你覆盖它 - 名义上的线程调度器将使用相同​​的策略来安排他们。他们会都坐在愉快纺循环。

Philosophically there is little difference between 1, 2 and 3 in how executing thread behaves. They all share the same default execution priority unless you override it - notionally the thread scheduler would use the same strategy to schedule them. They'd all sit happily spinning in the loop.

我怀疑方法之间的较大差异是:

I suspect the bigger difference between methods is:

  1. 在基础设施成本(线程,内存等)纺,以支持的#2,#3线程池,所有这些都将争夺的时钟时间片与你的执行循环。
  2. 在线程上下文就少了,肌肉的Atom转换成本。原子具有较小的高速缓存, 和较短的处理流水线(多个)。多个正在运行的线程=更多的上下文切换,更倾倒管道(S)和精简指令高速缓冲存储器的效率。
  1. infrastructure cost (threads, memory etc.) spun up to support threadpool of #2 and #3 all of which will contend for clock timeslices with your execution loop.
  2. thread context switching cost on the less-muscular Atom. The Atom has a smaller caches, and shorter processing pipeline(s). More running threads = more context switches, more dumping of pipeline(s) and reduced instruction cache efficiency.

但从使用方法2和3的功能上有些辱骂 - 你的意图是永远不会退出方法。这些策略的原子,有限的运营,而且有些非制导执行经常适用于IO完成端口的任务,比如异步网络,磁盘操作等...优化(也许有可能为你的串行端口code吗?)

From a functional point of view use of Method 2 and 3 are somewhat abusive - your intention is to never exit the method. These strategies are optimized for atomic, finite operations, and somewhat unguided execution oft suited for IO Completion port tasks such as async network, disk operations etc... (Maybe a possibility for your serial port code too?)

我会跳过2及3,除非你有兴趣在适应异步IO。重点线 - 看起来像你想更细的颗粒,没有基础设施的开销线程池带来predictable执行控制。

I would skip 2 & 3 unless you're interested in adapting to Async IO. Focus on thread - seems like you're wanting finer grain, predictable execution control without the infrastructure overhead that Threadpool brings.

这篇关于.NET线程VS线程池VS任务进行的SerialPort通讯的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆