Execute .NET Core 3.1 background worker tasks simultaneously I have following code:
public class Worker : BackgroundService
{

    public Worker()
    {
    }

    protected async override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            var task1 = Task.Run(() =&gt;
                MethodOneAsync(stoppingToken)
            ).ContinueWith(_ =&gt; Debug.WriteLine($&quot;MethodOneAsync finished @ {DateTime.Now:dd.MM.yyyy HH:mm:ss.ffff}&quot;));
            var task2 = Task.Run(() =&gt;
                MethodTwoAsync(stoppingToken)
            ).ContinueWith(_ =&gt; Debug.WriteLine($&quot;MethodTwoAsync finished @ {DateTime.Now:dd.MM.yyyy HH:mm:ss.ffff}&quot;));

            await Task.WhenAll(task1, task2);

            await Task.Delay(10000);
        }
    }

    private async Task&lt;bool&gt; MethodOneAsync(CancellationToken stoppingToken)
    {
        Debug.WriteLine($&quot;MethodOneAsync started @ {DateTime.Now:dd.MM.yyyy HH:mm:ss.ffff}&quot;);
        await Task.Delay(1000); // emulating some long work

        return true;
    }

    private async Task&lt;bool&gt; MethodTwoAsync(CancellationToken stoppingToken)
    {
        Debug.WriteLine($&quot;MethodTwoAsync started @ {DateTime.Now:dd.MM.yyyy HH:mm:ss.ffff}&quot;);
        await Task.Delay(1000); // emulating some long work

        return true;
    }
}

What I want to achieve is:

to create background worker that will call MethodOneAsync and MethodTwoAsync on separate threads (start both tasks simultaneously)
log time each task started and finished
wait for them both to finish
then wait another 10 seconds
repeat all over again

The code I wrote does its job as expected.
Since I am still trying to get a grasp of .NET Core tasks, I would like to know is this the right way to do it?
Async method out-of-the-box is using multiple threads for continuations. (Everything after await is continuation). Exception of this rule if existing SynchronizationContext. Don't Task.Run asynchronous I/O-bound operation, do it only for synchronous CPU-bound one. Asynchronous programming, SynchrinizationContext &amp; TaskScheduler.
Mixing .ContinueWith and await is not recommended as it doing the same but using different coding pattern. Mixing patterns with no reason makes the code more complicated.

If I were you, the code could look like this:
public class Worker : BackgroundService
{
    protected async override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        // all methods will throw OperationCanceledException if cancellation was happened,
        // then checking if it was canceled is a kind of redundancy here.
        while (true) 
        {
            var task1 = MethodOneAsync(stoppingToken);
            var task2 = MethodTwoAsync(stoppingToken);
            await Task.WhenAll(task1, task2, Task.Delay(10000, stoppingToken)); // inlining Task.Delay here changes the logic: 10 seconds counted between starts of two iterations not between finish of previous and start of next.
        }
    }

    private async Task MethodOneAsync(CancellationToken stoppingToken)
    {
        Debug.WriteLine($&quot;MethodOneAsync started @ {DateTime.Now:dd.MM.yyyy HH:mm:ss.ffff}&quot;);
        await Task.Delay(1000, stoppingToken);
        Debug.WriteLine($&quot;MethodOneAsync finished @ {DateTime.Now:dd.MM.yyyy HH:mm:ss.ffff}&quot;);
    }

    private async Task MethodTwoAsync(CancellationToken stoppingToken)
    {
        Debug.WriteLine($&quot;MethodTwoAsync started @ {DateTime.Now:dd.MM.yyyy HH:mm:ss.ffff}&quot;);
        await Task.Delay(1000, stoppingToken);
        Debug.WriteLine($&quot;MethodTwoAsync finished @ {DateTime.Now:dd.MM.yyyy HH:mm:ss.ffff}&quot;);
    }
}

About Worker class purpose. It looks like Scheduler not Worker because it repeats some work continuously. Consider to change its name.