What is an efficient way to run C # tasks in sequence

I am trying to find a way to schedule tasks in sequence. The solution I came up with is published below, but I have a suspicion that it can be done much easier / more efficiently.

public class SequentialTaskRunner { private ISet<Task> runningTasks = new HashSet<Task>(); public void Run(Task task) { lock (runningTasks) { var tasksToAwait = runningTasks.ToArray(); // create a task that waits for the currently running tasks var waitingTask = Task.Factory.StartNew(() => { Task.WaitAll(tasksToAwait); }); // make sure the task gets removed from the running tasks on completion task.ContinueWith((antecedent2) => { lock (runningTasks) { runningTasks.Remove(task); } }); // prepend the waiting task waitingTask.ContinueWith((antecedent) => task.Start()); runningTasks.Add(task); } } } 

I want to use this to perform tasks related to com-port connections so that they do not fall into each other.

The situation is this: I am working with an rfid device. There are 2 drivers playing. 1 for read / write. Another that can scan available COM ports on demand to find a (different) reader. Port scans are sometimes performed using a reader driver to reconnect. These are precisely these β€œport” scan tasks that I don’t want to combine.

I hope this will explain how I got into a situation where you had to not perform two tasks at the same time. Now there may be another way, not to mention answering this question. But I'm still very interested in what a good solution would be :)

+4
source share
2 answers

(The entire previous post in the comments).

My new understanding is that you have 3 types of tasks.

  • Reader
  • Writer
  • Port scanner

You would like these three to be as parallel as possible, but you will also like Reader if he wants to go into port scanning so as not to do this while the scanner port is alive. One way to solve this problem is Semaphore . Semaphores control access to a limited amount of resources.

In your case, you have a limited amount (actually only 1) of resources ("port scan"). In this case, we could choose a simpler AutoResetEvent . However, I feel that Semaphore can actually reduce confusion.

 // Only 1 task may port scan at a time Semaphore portScanResource = new Semaphore(initialCount: 1, maximumCount: 1); // ... // "Reader task" var task = Task.Factory.StartNew( () => { // ... if (shouldPortScan) { portScanResource.WaitOne(); try { // do your port scan } finally { // we're done portScanResource.Release(); } } }); 

The Port Scanner task will use the same Semaphore , ensuring that only one thread scans ports at a time.

+4
source

if you are in C # 4, you can ConcurrentQueue class that is thread safe for your queue

or see other Concurrent * classes in C4. Parallel extensions are also very convenient, but oyu will need to configure it on the fly.

0
source

All Articles