C# 任务行为
C# Task behaviour
您好,我有一个关于任务的简短问题。据我了解任务本身可以启动多个线程。
假设我有两个硬件传感器,它们通过两个不同的数据端口为我提供数据。
我想在我的 c# 项目中将它们作为生产者实施,然后对数据进行处理。在两个不同的任务中开始数据收集是否有意义?或者我应该在同一个任务中实现它们,因为 c# 会自动将它们放在不同的线程上?
var producerWorker = Task.Factory.StartNew(() => SensorB(number));
var producerWorker2 = Task.Factory.StartNew(() => SensorA(number));
或
var producerWorker = Task.Factory.StartNew(() => Sensor_A_AND_B(number));
我的第二个问题是:当我在两个不同的任务中有两个不同的生产者时,如果它们具有不同的数据类型但需要在队列中的相同位置,我该如何将它们的数据添加到同一个 BlockingCollection 队列中?
例如,如果我有 SensorA 的 queueA、SensorB 的 queueB 和 queueC。
两个队列可以以不同的速度填充。所以假设 queueA 有 50 个元素,但 SensorB 快得多并且已经有 100 个元素存储在 queueB 中。但是我需要以某种方式检索数据,以便我可以将 queueA[33].data 和 queueB[33].data 放在 queueC[33].data 中。当然我不想从 element33 开始,但总是从存储在 queueA 和 queueB 中的第一个元素开始....
我希望你能明白我的意思
任务以运行时间认为最好的方式执行。通常,在可用线程上有一个线程池和两个任务 运行。如果你真的需要并行轮询两个传感器,我建议你使用两个真正的线程来轮询并使用 Reactive Extensions 来同步处理读数。
根据您的问题判断,您应该阅读一些有关 C# 中的任务和异步工作原理的文章,该主题太大而无法回答堆栈溢出问题。我建议拿起一本书,因为 MS。在提供坚实的知识块方面,文档是垃圾。
简而言之,一个任务不能在其内部启动多个线程。从概念上讲,任务是比线程更小的单元。一个线程可以处理多个任务,假设你有 20 个任务,C# 运行时将有一个线程池,例如 4 个线程,它们将分别执行一个任务,处理它,然后继续下一个任务等等。
也许你指的是异步操作。这是一个与线程截然不同的野兽。基本上你要求计算机的某些部分关闭,做一个独立的工作,例如通过网络发送数据并在完成时通知你的程序,同时不阻塞线程。
避免使用 Task.Factory
,因为它有很多搬起石头砸自己脚的方法。Take a look at Stephen Cleary blog。大多数时候 Task.Run(...
是更好的选择。
我最好的猜测是当你说:
Or should i implement them in the same task since c# will automatically put them on different threads?
您指的是异步操作。
为简单起见,您可以创建两个单独的任务,并在它们收到数据后立即将其弹出到队列中。
您的问题表明您需要同步传入的 data.If 是这样,阻塞队列可能是错误的选择。改用并发队列。不同的任务可以读取 QueueA[x] 和 QueueB[x],并缓冲传入的数据。然后,当 A 和 B 都提供第 N 个结果时,您可以弹出到 QueueC。
您好,我有一个关于任务的简短问题。据我了解任务本身可以启动多个线程。
假设我有两个硬件传感器,它们通过两个不同的数据端口为我提供数据。
我想在我的 c# 项目中将它们作为生产者实施,然后对数据进行处理。在两个不同的任务中开始数据收集是否有意义?或者我应该在同一个任务中实现它们,因为 c# 会自动将它们放在不同的线程上?
var producerWorker = Task.Factory.StartNew(() => SensorB(number));
var producerWorker2 = Task.Factory.StartNew(() => SensorA(number));
或
var producerWorker = Task.Factory.StartNew(() => Sensor_A_AND_B(number));
我的第二个问题是:当我在两个不同的任务中有两个不同的生产者时,如果它们具有不同的数据类型但需要在队列中的相同位置,我该如何将它们的数据添加到同一个 BlockingCollection 队列中?
例如,如果我有 SensorA 的 queueA、SensorB 的 queueB 和 queueC。 两个队列可以以不同的速度填充。所以假设 queueA 有 50 个元素,但 SensorB 快得多并且已经有 100 个元素存储在 queueB 中。但是我需要以某种方式检索数据,以便我可以将 queueA[33].data 和 queueB[33].data 放在 queueC[33].data 中。当然我不想从 element33 开始,但总是从存储在 queueA 和 queueB 中的第一个元素开始....
我希望你能明白我的意思
任务以运行时间认为最好的方式执行。通常,在可用线程上有一个线程池和两个任务 运行。如果你真的需要并行轮询两个传感器,我建议你使用两个真正的线程来轮询并使用 Reactive Extensions 来同步处理读数。
根据您的问题判断,您应该阅读一些有关 C# 中的任务和异步工作原理的文章,该主题太大而无法回答堆栈溢出问题。我建议拿起一本书,因为 MS。在提供坚实的知识块方面,文档是垃圾。
简而言之,一个任务不能在其内部启动多个线程。从概念上讲,任务是比线程更小的单元。一个线程可以处理多个任务,假设你有 20 个任务,C# 运行时将有一个线程池,例如 4 个线程,它们将分别执行一个任务,处理它,然后继续下一个任务等等。
也许你指的是异步操作。这是一个与线程截然不同的野兽。基本上你要求计算机的某些部分关闭,做一个独立的工作,例如通过网络发送数据并在完成时通知你的程序,同时不阻塞线程。
避免使用 Task.Factory
,因为它有很多搬起石头砸自己脚的方法。Take a look at Stephen Cleary blog。大多数时候 Task.Run(...
是更好的选择。
我最好的猜测是当你说:
Or should i implement them in the same task since c# will automatically put them on different threads?
您指的是异步操作。
为简单起见,您可以创建两个单独的任务,并在它们收到数据后立即将其弹出到队列中。 您的问题表明您需要同步传入的 data.If 是这样,阻塞队列可能是错误的选择。改用并发队列。不同的任务可以读取 QueueA[x] 和 QueueB[x],并缓冲传入的数据。然后,当 A 和 B 都提供第 N 个结果时,您可以弹出到 QueueC。