thethakuri
thethakuri

Reputation: 511

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?

Upvotes: 0

Views: 1366

Answers (2)

ByungYong Kang
ByungYong Kang

Reputation: 181

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

Upvotes: 2

thethakuri
thethakuri

Reputation: 511

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

Upvotes: 2

Related Questions