C# 如何确定是否可以使用CancellationTokenSource取消某个异步任务?

C# 如何确定是否可以使用CancellationTokenSource取消某个异步任务?,c#,C#,我想知道是否可以使用CancellationTokenSource取消任务。如何确定是否可以取消某个异步任务 public async Task PlayerAccountDetails() { CancellationTokenSource cts = new CancellationTokenSource(); try { await UpdatePlayerCountryData("Germany", "Berlin"); } ca

我想知道是否可以使用CancellationTokenSource取消任务。如何确定是否可以取消某个异步任务

public async Task PlayerAccountDetails()
{
    CancellationTokenSource cts = new CancellationTokenSource();

    try
    {
        await UpdatePlayerCountryData("Germany", "Berlin");
    }
    catch (Exception ex)
    {
        var excep = ex.Message;
    }
}

private static async Task UpdatePlayerCountryData(string country, string city)
{
    var resultprofile = await PlayFabClientAPI.UpdateUserDataAsync(new PlayFab.ClientModels.UpdateUserDataRequest()
    {
        Data = new Dictionary<string, string>() {
               {"Country", country},
               {"City", city}},
               Permission = PlayFab.ClientModels.UserDataPermission.Public
    });

    if (resultprofile.Error != null)
        Console.WriteLine(resultprofile.Error.GenerateErrorReport());
    else
    {
        Console.WriteLine("Successfully updated user data");
    }
}

这是一个实际的例子:

class Program
{
    static void Main(string[] args)
    {
        var cancellationTokenSource = new CancellationTokenSource();
        var task = Task.Run(async () => await WatchYourCarBurn(cancellationTokenSource.Token));

        Task.Run(async () => await Task.Delay(5000)).Wait();
        Console.WriteLine("Too much time elapsed, cancel task.");
        cancellationTokenSource.Cancel();

        while (!task.IsCompleted && !task.IsCanceled)
        {

        }
    }

    private static async Task WatchYourCarBurn(CancellationToken token)
    {
        Console.WriteLine("You notice some fog");

        await Task.Delay(2000);

        token.ThrowIfCancellationRequested();

        Console.WriteLine("You notice some fire");

        await Task.Delay(2000);

        token.ThrowIfCancellationRequested();

        Console.WriteLine("You notice your car");

        await Task.Delay(2000);

        token.ThrowIfCancellationRequested();

        Console.WriteLine("You notice your car is burning");

        await Task.Delay(2000);

        token.ThrowIfCancellationRequested();

        Console.WriteLine("You watch your car burning");

        await Task.Delay(2000);
    }
}
如何确定是否可以取消某个异步任务

public async Task PlayerAccountDetails()
{
    CancellationTokenSource cts = new CancellationTokenSource();

    try
    {
        await UpdatePlayerCountryData("Germany", "Berlin");
    }
    catch (Exception ex)
    {
        var excep = ex.Message;
    }
}

private static async Task UpdatePlayerCountryData(string country, string city)
{
    var resultprofile = await PlayFabClientAPI.UpdateUserDataAsync(new PlayFab.ClientModels.UpdateUserDataRequest()
    {
        Data = new Dictionary<string, string>() {
               {"Country", country},
               {"City", city}},
               Permission = PlayFab.ClientModels.UserDataPermission.Public
    });

    if (resultprofile.Error != null)
        Console.WriteLine(resultprofile.Error.GenerateErrorReport());
    else
    {
        Console.WriteLine("Successfully updated user data");
    }
}
在一般情况下,你不能

一种是可取消异步方法将CancellationToken作为参数,例如,检查此重载:

await UpdatePlayerCountryData("Germany", "Berlin", cts.Token);

但是,有时该参数会被忽略,因此不能保证取消请求会得到满足。

您不取消任务,而是取消方法。该方法必须接受CancellationToken,并且必须定期检查它是否已被取消。如果您询问是否可以取消UpdateUserDataAsync方法,那么请检查是否存在接受CancellationTokenCancellation的重载。如果您调用的代码不知道取消令牌,则它不可能观察到取消并提前终止其活动。请使用cancellationToken.ThrowIfCancellationRequested和Task.Run…,cancellationToken。这样,任务将显示为已取消。将等待任务。延迟5000。等待是否阻止线程?我不想阻止它。@canton7我到底应该改变什么?我不知道你的意思:cancellationToken.ThrowifcCancellationRequested和Task.Run…,cancellationToken,而不是do if token.IsCancellationRequested返回,do token.ThrowifcCancellationRequested。如果发生取消,则抛出可识别的异常。而不是执行Task.Runasync=>Wait Watch YourCancellationTokenSource.Token,执行Task.Runasync=>Wait Watch YourCancellationTokenSource.Token,cancellationTokenSource.Token。这会告诉Task.Run识别来自您提供给它的CancellationToken的异常,并将它返回的任务标记为已取消,而不是Faulted@canton7编辑我的答案,如果不使用token.ThrowIfCancellationRequested,有效IsCanceled永远不会为true;