[SOLVED] How to run multiple tasks simultaneously in the background of a IHostedService

Issue

I have an ASP.NET Core application that runs an IHostedService class as an background worker. Now I have two Tasks which run endlessly.

  • Task1: Has an WebSocket connection that continuously receives data and stores it in the MSSQL database using EF Core
  • Task2: Runs an endless loop which every 10 seconds runs over the Transactions that have been added to the database in Task1

Now my question is:
How do I let these two Tasks run simultaneously? Because right now Task1 is blocking Task2 from executing. Any help or suggestions on how to better solve this problem would be greatly appreciated.

IHostedService

public async Task StartAsync(CancellationToken cancellationToken)
{
    await Task1();
    new Thread(Task2).Start();
}

public async Task Task1()
{
    using (var client = new StreamingWebSocketClient("wss://websocket.io"))
    {
       //Receive data from Websocket and store in MSSQLDB using EF Core
    }
}

private void Task2()
{
    using (_dbContext)
    {
        while (true)
        {
            var transactions = _dbContext.Transactions.Where(t => t.To == null).ToList();

            foreach (Models.Transaction transaction in transactions)
            {
                //Do some work
            }
            Thread.Sleep(10000);
        }
    }
}

Solution

Don’t await the first task until the second one runs:

public async Task StartAsync(CancellationToken cancellationToken)
{
    var task1 = Task1();
    var task2 = Task.Run(() => Task2());
    await Task.WhenAll(task1, task2);
}

This gets slightly better when you do this:

public async Task StartAsync(CancellationToken cancellationToken)
{
    var task1 = Task1();
    var task2 = Task2(cancellationToken);
    await Task.WhenAll(task1, task2);
}


private async Task Task2(CancellationToken cancellationToken)
{
    using (var dbContext = new DbContext())
    {
        while (true)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                break;
            }
            else
            {
                var transactions = dbContext.Transactions.Where(t => t.To == null).ToList();
                foreach (Models.Transaction transaction in transactions)
                {
                    //Do some work
                }
                await Task.Delay(TimeSpan.FromSeconds(10.0));
            }
        }
    }
}

Answered By – Enigmativity

Answer Checked By – David Marino (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *