7

Is it possible to cancel all async methods, without knowing what is currently running?

For example I have several classes that may run async tasks:

class Class1 { public async void SomeTask() { for (int i = 0; i < 5; i++) { // Doing some job await Task.Delay(2000); } } } class Class2 { public async void ContinuouslyTask() { for (;;) { // Doing some job on background await Task.Delay(1000); } } } 

And I want turn off every async task, before I will logout:

class Program { static void Main(string[] args) { var p = new Program(); var c1 = new Class1(); var c2 = new Class2(); c1.SomeTask(); c2.ContinuouslyTask(); while (Console.ReadKey().Key != ConsoleKey.Enter) { } p.Logout(); } private void Logout() { // Cancel all async tasks // And do logout work } } 

Is it possible to do this, without saving tasks into query?

2 Answers 2

4

This is basically extending @FrankFajardo answer to provide a concrete example. When you pass in a CancellationToken, you also need to monitor it for any cancellation request from the outside. It will look like this:

class Class1 { public async Task SomeTaskAsync(CancellationToken cancellationToken) { for (int i = 0; i < 5; i++) { if (cancellationToken.IsCancellationRequested) break; // Doing some job await Task.Delay(2000); } } } class Class2 { public async Task ContinuouslyTaskAsync(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { // Doing some job on background await Task.Delay(1000); } } } 

And now when you want to cancel it, you simply add CancellationTokenSource.Cancel() call to your code:

static void Main(string[] args) { var p = new Program(); var c1 = new Class1(); var c2 = new Class2(); var cancellationTokenSource = new CancellationTokenSource(); var someTask = c1.SomeTask(cancellationTokenSource.Token); var continuousTask = c2.ContinuouslyTask(cancellationTokenSource.Token); while (Console.ReadKey().Key != ConsoleKey.Enter) { } cancellationTokenSource.Cancel(); Task.WaitAll(someTask, continuousTask); p.Logout(); } 

Note I'm using Task.WaitAll only because this is a console application where Main can't be async. Otherwise, use Task.WhenAll which returns an awaitable Task.

Sign up to request clarification or add additional context in comments.

Comments

3

You should look at CancellationTokenSource.

You should make your c1.SomeTask() and c2.ContinuouslyTask() accept cancellation tokens, and check for that token to see if the reques is being cancelled, and end abruptly if so.

Then in your Program.Main(), it should create a CancellationTokenSource and pass the CancellationTokenSource.Token to the 2 async method it calls. This CancellationTokenSource should be accessible to the Program.Logout() so that it can issue the cancellation on logout. See example here

NOTE: It is generally advised that async methods return Tasks, instead of void. Also, it is a convention that async methods are named xxxAsync (eg. DoWorkAsync).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.