Home > database >  Handling Async/Await Cancellation in C# Service Application
Handling Async/Await Cancellation in C# Service Application

Time:03-04

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?

CodePudding user response:

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();
}

CodePudding user response:

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();
}
  • Related