Wood YANG
Wood YANG

Reputation: 23

How to set timeout for a task, and then abort it

class Program
{
    static async Task Main(string[] args)
    {
        Console.WriteLine($"The main thread is {Thread.CurrentThread.ManagedThreadId}");
        var cts = new CancellationTokenSource();
        Person p = new Person { Name = "Apple" };
        try
        {
            cts.CancelAfter(TimeSpan.FromSeconds(3));//limited to 3 seconds
            DoSth(p).Wait(cts.Token);
        }
        catch
        {

        }
        Console.WriteLine(cts.Token.IsCancellationRequested);
        Thread.Sleep(3000);
        Console.ReadLine();
    }

    static async Task DoSth(Person p)
    {
        await Task.Run(() =>
        {
            p.Name = "Cat";
            Thread.Sleep(5000); 
            
            Console.WriteLine($"The async thread is {Thread.CurrentThread.ManagedThreadId}");
        });
    }
}

As you can see the code as above, I got the output:

The main thread is 1
True
The async thread is 4

It seems that method is still running after cancellation? Is it possible to abort the task in some time? When I'm trying to use Thread.Abort(), I got an alert that the method is obsolete.

Upvotes: 0

Views: 4102

Answers (1)

Magnus
Magnus

Reputation: 46919

If you want to abort the task after 3s you need to send the token to the function. If you use Task.Delay and send in the token that will throw an exception on cancellation and abort the task.

class Program
{
    static async Task Main(string[] args)
    {
        Console.WriteLine($"The main thread is {Thread.CurrentThread.ManagedThreadId}");
        var cts = new CancellationTokenSource();
        Person p = new Person { Name = "Apple" };
        try
        {
            cts.CancelAfter(TimeSpan.FromSeconds(3));//limited to 3 seconds
            await DoSth(p, cts.Token);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message); //task was canceled
        }
        Console.WriteLine(cts.Token.IsCancellationRequested);
        await Task.Delay(3000);
        Console.ReadLine();
    }

    static async Task DoSth(Person p, CancellationToken ct)
    {
        p.Name = "Cat";
        await Task.Delay(5000, ct); //Will throw on cancellation, so next row will not run if cancelled after 3s.
        Console.WriteLine($"The async thread is {Thread.CurrentThread.ManagedThreadId}");
    }
}

public class Person
{
    public string Name { get; set; }
}

Upvotes: 3

Related Questions