非同步任務取消、超時

DaiWK發表於2024-06-19

一、定義非同步任務

//定義非同步任務
public class AsyncClass
{
    public static async Task TaskAsync(CancellationToken token)
    {
        token.Register(() => { Console.WriteLine("TaskAsync被取消"); });

        for (int i = 0; i < 10; i++)
        {
            if (token.IsCancellationRequested)
            {
                token.ThrowIfCancellationRequested();
            }
            await Task.Delay(1000);
            Console.WriteLine($"TaskAsync:{i}");
        }
    }

    public static async Task TaskAsync1(CancellationToken token)
    {
        token.Register(() => { Console.WriteLine("TaskAsync1 is Cancel"); });

        for (int i = 0; i < 10; i++)
        {
            if (token.IsCancellationRequested)
            {
                token.ThrowIfCancellationRequested();
            }
            await Task.Delay(1000);
            Console.WriteLine($"TaskAsync1:{i}");
        }
    }
}

二、實現非同步任務取消

#region 取消
var cts = new CancellationTokenSource();
try
{
    var token = cts.Token;

    token.Register(() => { Console.WriteLine("Main 被取消"); });//當前執行緒取消提示

    cts.CancelAfter(3000);//3秒後取消

    //cts.Cancel();

     await AsyncClass.TaskAsync(token);
}
catch (OperationCanceledException ex)
{
    Console.WriteLine(ex.ToString());
}
catch (TimeoutException ex)
{
    Console.WriteLine(ex.ToString());
}
finally
{
    cts.Dispose();
}
#endregion

三、實現非同步任務超時

#region 超時

var TimeOutCts = new CancellationTokenSource();
try
{
    var TimeOutToken = TimeOutCts.Token;
    //方式一
    //var mytask = AsyncClass.TaskAsync(TimeOutToken);
    //var completedTask = await Task.WhenAny(mytask, Task.Delay(2000, TimeOutToken));
    //if (completedTask != mytask)
    //{
    //    throw new TimeoutException("TaskAsync超時了");//手動丟擲超時異常
    //}

    //方式二
    await AsyncClass.TaskAsync1(TimeOutToken).WaitAsync(TimeSpan.FromMilliseconds(2000));

}
catch (TimeoutException ex) 
{
    TimeOutCts.Cancel();//捕獲超時異常,取消任務
    Console.WriteLine(ex.ToString());
}
catch (OperationCanceledException ex)
{
    Console.WriteLine(ex.ToString());
}
finally
{
    TimeOutCts.Dispose();
}
#endregion

四、執行結果

相關文章