Skip to content

C# 多线程 05-使用 C#6.0 03-对连续的异步任务使用 await 操作符

🏷️ 《C# 多线程》

对连续的异步任务使用 await 操作符

csharp
/// <summary>
/// 对连续的异步任务使用 await 操作符
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
    Task t = AsynchronyWithTPL();
    t.Wait();

    t = AsynchronyWithAwait();
    t.Wait();

    Console.ReadLine();
}

/// <summary>
/// 使用 TPL 方式的实现
/// 功能等同于 AsynchronyWithAwait 方法的功能
/// 但是写法复杂很多
/// </summary>
/// <returns></returns>
static Task AsynchronyWithTPL()
{
    var containerTask = new Task(() => {
        Task<string> t = GetInfoAsync("TPL 1");
        t.ContinueWith(task => {
            Console.WriteLine(t.Result);
            Task<string> t2 = GetInfoAsync("TPL 2");
            t2.ContinueWith(innerTask => Console.WriteLine(innerTask.Result),
                TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.AttachedToParent);
            t2.ContinueWith(innerTask => Console.WriteLine(innerTask.Exception.InnerException),
                TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent);
        }, TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.AttachedToParent);

        t.ContinueWith(task => Console.WriteLine(t.Exception.InnerException),
            TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent);
    });
    containerTask.Start();
    return containerTask;
}

static async Task AsynchronyWithAwait()
{
    try
    {
        // 使用了两个 await 操作符,但代码还是按顺序执行的
        string result = await GetInfoAsync("Async 1");
        Console.WriteLine(result);
        result = await GetInfoAsync("Async 2");
        Console.WriteLine(result);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}

static async Task<string> GetInfoAsync(string name)
{
    Console.WriteLine($"Task {name} started!");
    await Task.Delay(TimeSpan.FromSeconds(2));
    if (name == "TPL 2" || name == "Async 2")
    {
        throw new Exception("Boom!");
    }
    return $"Task {name} is running on a thrad id {Thread.CurrentThread.ManagedThreadId}. " +
        $"Is thread pool thread: {Thread.CurrentThread.IsThreadPoolThread}";
}

打印结果

txt
Task TPL 1 started!
Task TPL 1 is running on a thrad id 4. Is thread pool thread: True
Task TPL 2 started!
System.Exception: Boom!
   在 Recipe5_3.Program.<GetInfoAsync>d__3.MoveNext() 位置 C:\Users\liujiajia\So
urce\Repos\learn-multi-threading\Recipe5-3\Program.cs:行号 72
Task Async 1 started!
Task Async 1 is running on a thrad id 3. Is thread pool thread: True
Task Async 2 started!
System.Exception: Boom!
   在 Recipe5_3.Program.<GetInfoAsync>d__3.MoveNext() 位置 C:\Users\liujiajia\So
urce\Repos\learn-multi-threading\Recipe5-3\Program.cs:行号 72
--- 引发异常的上一位置中堆栈跟踪的末尾 ---
   在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
   在 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   在 Recipe5_3.Program.<AsynchronyWithAwait>d__2.MoveNext() 位置 C:\Users\liuji
ajia\Source\Repos\learn-multi-threading\Recipe5-3\Program.cs:行号 57