0

Hi I have a short question regarding tasks. As far as I understand Tasks can start multiple threads in itself.

Lets say I have two hardware sensors which give me data over two different dataports.

I want to implement them as producers in my c# project and then do something with the data. Would it make sense to start the data collection in two different tasks? Or should i implement them in the same task since c# will automatically put them on different threads?

 var producerWorker = Task.Factory.StartNew(() => SensorB(number));
            var producerWorker2 = Task.Factory.StartNew(() => SensorA(number));

or

var producerWorker = Task.Factory.StartNew(() => Sensor_A_AND_B(number));

My second problem is: When I have two different producers in two different tasks, how do I add their data to the same BlockingCollection queue if they have different datatypes but need to be at the same position in the queue?

For example if I have queueA for SensorA, queueB for SensorB, and queueC. Both queues can be filled at different speeds. So lets say queueA has 50 elements, but SensorB is a lot faster and already has 100 elements stored in queueB. However I need to retrieve the data in a way, so that I can place queueA[33].data and queueB[33].data in queueC[33].data. Of course I would not like to start with element33, but always with the first element which was stored in queueA and queueB....

I hope you get what i mena

DerBenutzer
  • 311
  • 1
  • 5
  • 20

2 Answers2

1

Tasks are executed in whatever way the runtime thinks is the best. Generally, there's a thread pool and both tasks run on available threads. If you really need to poll two sensors in parallel, I would recommend you to use two real threads to poll and use Reactive Extensions to process the readings in sync.

Alexey
  • 1,354
  • 13
  • 30
0

Judging by your question, you should do some reading on how tasks and Async work in C#, the topic is too large to answer on stack overflow. I would recommend picking up a book, because MS. documentation is rubbish when it comes to providing a solid block of knowledge.

Brifly, a task can not start multiple threads inside itself. Conceptually, a task is a smaller unit than a thread. A single thread can process multiple tasks, so lets say you have 20 tasks, the c# runtime will have a thread-pool of, for example, 4 threads, and they will take a task each, process it, then move on to the next task, and so on.

Perhaps what you are referring to is Asyncronous operations. That's a very different beast than a thread. Basically you are asking some part of the computer to go off, do an independent piece of work, for example send data over network and notify your program when it's done, without blocking the thread in the meantime.

Avoid using Task.Factory, because it has many ways of shooting yourself in the foot.Take a look at Stephen Cleary blog. Task.Run(... is a better choice most of the time.

My best guess is that when you say:

Or should i implement them in the same task since c# will automatically put them on different threads?

You are referring to async operations.

For simplicity's sake you could create two separate tasks, and as soon as they recieve data pop it into a queue. Your question suggests that you need to synchronize the incoming data.If that's so, a blocking queue is probably the wrong choice. Use concurrent queue instead. A different task could read QueueA[x] and QueueB[x], and buffer the incoming data. Then you could pop then onto QueueC when both A and B supply N'th result.

Vladimir Akopyan
  • 644
  • 8
  • 16