如何为任务设置超时,然后中止它

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

如上代码所示,我得到了输出:

The main thread is 1
True
The async thread is 4

好像取消后方法还是运行? 是否有可能在一段时间内中止任务? 当我尝试使用 Thread.Abort() 时,我收到一条警告,提示该方法已过时。

如果你想在 3 秒后中止任务,你需要将令牌发送到函数。如果您使用 Task.Delay 并发送将在取消时抛出异常并中止任务的令牌。

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