'Handling Async/Await Cancellation in C# Service Application

I have a service that spins up a thread to listen for incoming tcp stream

protected override void OnStart(string[] args)
{
    worker = new Thread(ListenForStatus);
    worker.Start();
}

The listen method sends the recevied tcp stream to async task for processing, does not wait for it to complete and goes back to listening for tcp stream

private void ListenForStatus()
{
    while (!_shutdownEvent.WaitOne(0))
    {
         _ = ProcessEventAsync("string_to_process");
    }
}

private async Task ProcessEventAsync(string Status)
{
    await Task.Delay(10000);
    //Do Something
}

OnStop method breaks the loop and terminates the thread.

protected override void OnStop()
{
     _shutdownEvent.Set();
     worker.Join(2000);
}

Program is working as intended. But do I need to handle Cancellation of existing async tasks when the service is stopped and how do I implement it?



Solution 1:[1]

I have await Task.Delay() inside ProcessEventAsync method that I overloaded with CancellationToken.

private async Task ProcessEventAsync(string Status, CancellationToken token)
{
    await Task.Delay(10000, token);
    //Do Something
}

protected override void OnStop()
{
    cancellationTokenSource.Cancel();
}

Solution 2:[2]

Try this way...

protected override void OnStart(string[] args)
{
   cancellationTokenSource = new CancellationTokenSource();
   worker = new Task(ListenForStatus);
   worker.Start();
}

private void ListenForStatus()
{
    while (!cancellationTokenSource.IsCancellationRequested)
    {
        _ = ProcessEventAsync("...", cancellationTokenSource.Token);
    }
}

private async Task ProcessEventAsync(string Status, CancellationToken token)
{
    // Assume that you process something for loop
    for (int i = 0; i < 1000000; i++)
    {
        // you can break the loop by checking token
        if (token.IsCancellationRequested) break;

        //Do something

        // or
        await Task.Run(() =>
        {
            // do something
        }, token);

    }
}

protected override void OnStop()
{
    cancellationTokenSource.Cancel();
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 thethakuri
Solution 2