What is the best practice for running multiple background tasks

I have a Windows service (.NET 4.5.2) that should run several tasks in the background, while I want to use System.Threading.Tasks, which from the next implementation do you consider as best practice? Or am I completely wrong?

Scenario 1:

protected override void OnStart(string[] args)
{
    // Assume all tasks implemented the same way.
    // I believe we shouldn't await the tasks in this scenario.
    var token = this._cancellationTokenSource.Token;
    this.RunTask1(token);
    this.RunTask2(token);
    this.RunTask3(token);
}

private async Task RunTask1(CancellationToken token)
{
    var telebot = new Telebot("SOMETHING");
    while( true )
    {
        // Some work...
        // I/O dependent task.
        var response  = await telebot.GetUpdatesAsync(cancellationToken: token);

        //
        // Some other work
        // maybe some database calls using EF async operators.
        //
        await Task.Delay(TimeSpan.FromSeconds(1), token);
    }
}

Scenario 2:

protected override void OnStart(string[] args)
{
    // Assume all tasks implemented the same way.
    // I believe we shouldn't await the tasks in this scenario.
    var token = this._cancellationTokenSource.Token;
    this.RunTask1(token);
    this.RunTask2(token);
    this.RunTask3(token);
}

private void RunTask1(CancellationToken token)
{
    Task.Factory.StartNew(async () =>
        {
            var telebot = new Telebot("SOMETHING");
            while( true )
            {
                // Some work...
                // I/O dependent task.
                var response = await telebot.GetUpdatesAsync(cancellationToken: token);

                //
                // Some other work
                // may be some database calls using EF async operators.
                //
                await Task.Delay(TimeSpan.FromSeconds(1), token);
            }
        }, token);
}
+4
source share
2 answers

The method asyncis executed synchronously until the first await. After that, it will work in the ThreadPool thread (if it does not exist SynchronizationContext).

Thus, the use Task.Factory.StartNewor Task.Runnot recommended, as it tries to parallelize something that has been largely parallel.

, , , Task.Run ( Task.Factory.StartNew) , , .

, " 1" , " 2".

. , , :

protected override void OnStart()
{
    var token = _cancellationTokenSource.Token;
    _tasks.Add(RunTask1(token));
    _tasks.Add(RunTask2(token));
    _tasks.Add(Task.Run(() => RunTask3(token))); // assuming RunTask3 has a long synchronous part
}

List<Task> _tasks;

protected override void OnStop()
{
    _cancellationTokenSource.Cancel();
    Task.WhenAll(_tasks).Wait();
}
0

, ,

1. , .. . , , , , .

2. , Task Factory. , i.e , Task Factory.

, , - . , , .

+2

All Articles