0

I'm working on console EXE where I have to download particular data continuously, process on it and save its result in MSSQL DB.

I refer Never ending Task for single Task creation and it works for me for one method. I have 3 methods to execute simultaneously so I created 3 Task which I want to execute parallel continuously, so made few changes in code here is my code

CancellationTokenSource _cts = new CancellationTokenSource();
var parallelTask = new List<Task>
{
    new Task(
        () =>
        {
            while (!_cts.Token.WaitHandle.WaitOne(ExecutionLoopDelayMs))
            {
                DataCallBack(); // method 1
                ExecutionCore(_cts.Token);
            }
            _cts.Token.ThrowIfCancellationRequested();
         },
         _cts.Token,
         TaskCreationOptions.DenyChildAttach | TaskCreationOptions.LongRunning),
     new Task(
         () =>
         {
             while (!_cts.Token.WaitHandle.WaitOne(ExecutionLoopDelayMs))
             {
                 EventCallBack(); // method 2
                 ExecutionCore(_cts.Token);
             }
             _cts.Token.ThrowIfCancellationRequested();
         },
         _cts.Token,
         TaskCreationOptions.DenyChildAttach | TaskCreationOptions.LongRunning),
     new Task(
         () =>
         {
             while (!_cts.Token.WaitHandle.WaitOne(ExecutionLoopDelayMs))
             {
                 LogCallBack(); //method 3
                 ExecutionCore(_cts.Token);
             }
             _cts.Token.ThrowIfCancellationRequested();
         },
         _cts.Token,
         TaskCreationOptions.DenyChildAttach | TaskCreationOptions.LongRunning)
};

Parallel.ForEach(parallelTask, task =>
{
    task.Start();
    task.ContinueWith(x =>
    {
        Trace.TraceError(x.Exception.InnerException.Message);
        Logger.Logs("Error: " + x.Exception.InnerException.Message);
        Console.WriteLine("Error: " + x.Exception.InnerException.Message);
    }, TaskContinuationOptions.OnlyOnFaulted);
});                

Console.ReadLine();

I want to execute method 1, method 2 and method 3 parallel. But when I tested it only method3 is executing
I searched for alternate but did not found suitable guidance. is there any proper efficient way to do it.

wes
  • 379
  • 3
  • 15
Dark S
  • 308
  • 2
  • 15
  • Does this post give you some insight to resolve your issue: https://stackoverflow.com/questions/12343081/run-two-async-tasks-in-parallel-and-collect-results-in-net-4-5/13542080 – wes Dec 06 '19 at 10:53
  • I don't want to sleep those tasks plus its endless call means until something went wrong with input data it will not gonna stop. code i post was working fine when i create only one task and run it. but when created 3 and call it parallel, only last one is executing – Dark S Dec 06 '19 at 11:00
  • 1
    You shouldn't sleep in a task. A better solution is task.delay for async programming. – wes Dec 06 '19 at 11:09
  • @wes, ok I will try it as well! – Dark S Dec 06 '19 at 12:00
  • You have probably chosen the worst answer from the question you linked. The best one in my opinion is [this](https://stackoverflow.com/questions/13695499/proper-way-to-implement-a-never-ending-task-timers-vs-task/13695674#13695674). – Theodor Zoulias Dec 06 '19 at 12:27

1 Answers1

1

There is no need use Parallel.ForEach as you already have 3 tasks. This should do it:

var actions = new Action[] { EventCallBack, LogCallBack, DataCallBack };

await Task.WhenAll(actions.Select(async action =>
{
    while (!_cts.Token.IsCancellationRequested)
    {
        action();
        ExecutionCore(_cts.Token);
        await Task.Delay(ExecutionLoopDelayMs, _cts.Token)
    }
}, _cts.Token));
Magnus
  • 45,362
  • 8
  • 80
  • 118