开发者

C#中的Task使用方式

目录
  • 前言
  • Task 的基本概念
  • 创建 Task
    • 使用异步方法
    • 使用 Task.Run 方法
  • 等待 Task 完成
    • 使用 await 关键字
    • 使用 Task.Wait 方法
  • 处理 Task 的异常
    • 使用 try-catch 块
    • 使用 Task.Exception 属性
  • Task 的延续
    • 使用 ContinueWith 方法
    • 使用 await 关键字和异步方法
  • Task 的并行执行
    • 使用多个 Task
    • 使用 Task.WhenAll 方法
  • 总结

    前言

    在 C# 中,Task代表一个异步操作。它允许你在不阻塞主线程的情况下执行耗时的操作,从而提高应用程序的响应性和性能。本教程将详细介绍 C# 中的Task。

    Task 的基本概念

    Task是.NET Framework 4.0 引入的一种异步编程模型,它代表一个可能尚未完成的操作。

    Task可以表示任何异步操作,例如文件读取、网络请求、数据库查询等。与传统的异步编程模型相比,Task提供了一种更加简洁和高效的方式来处理异步操作。

    创建 Task

    使用异步方法

    C# 中的异步方法通常以async关键字开头,并返回一个Task或Task。

    例如:

       async Task<int> CalculateSumAsync()
       {
           int sum = 0;
           for (int i = 0; i < 100; i++)
           {
               sum += i;
           }
           return sum;
       }

    在这个例子中,CalculateSumAsync方法是一个异步方法,它返回一个Task,表示一个异步操作,该操作将计算从 0 到 99 的整数之和,并返回结果。

    使用 Task.Run 方法

    Task.Run方法可以将一个委托作为参数,并在一个新的线程上执行该委托。

    例如:

       Task<int> task = Task.Run(() =>
       {
           int sum = 0;
           for (int i = 0; i < 100; i++)
           {
               sum += i;
           }
           return sum;
       });

    在这个例子中,Task.Run方法将一个 lambda 表达式作为参数,编程该表达式计算从 0 到 99 的整数之和,并返回结果。

    Task.Run方法返回一个Task,表示在新线程上执行的异步操作。

    等待 Task 完成

    使用 await 关键字

    await关键字用于等待一个Task完成。当使用await关键字等待一个Task时,当前方法会暂停执行,直到Task完成。

    例如:

       async Task<int> CalculateSumAsync()
       {
           int sum = 0;
           for (int i = 0; i < 100; i++)
           {
               sum += i;
           }
           return sum;
       }
    
       async Task Main()
       {
           int result = await CalculateSumAsync();
           Console.WriteLine(result);
       }

    在这个例子中,Main方法是一个异步方法,它调用CalculateSumAsync方法,并使用await关键字等待该方法完成。

    一旦CalculateSumAsync方法完成,result变量将被赋值为该方法的返回值,并在控制台上输出结果。

    使用 Task.Wait 方法

    Task.Wait方法用于等待一个Task完成。与await关键字不同,Task.Wait方法会阻塞当前线程,直到Task完成。

    例如:

       Task<int> task = Task.Run(() =>
       {
           int sum = 0;
           for (int i = 0; i < 100; i++)
           {
               sum += i;
           }
           return sum;
       });
    
       task.Wait();
       int result = task.Result;
       Console.WriteLine(result);

    在这个例子中,task.Wait()方法会阻塞当前线程,直到task完成。

    一旦task完成,result变量将被赋值为task的返回值,并在控制台上输出结果。

    处理 Task 的异常

    使用 try-catch 块

    当等待一个Task时,可以使用try-catch块来捕获Task中发生的异常。

    例如:

       async Task<int> CalculateSumAsync()
       {
           int sum = 0;
           for (int i = 0; i < 100; i++)
           {
               sum += i;
           }
           throw new Exception("An error occurred.");
           return sum;
       }
    
       async Task Main()
       {
           try
           {
               int result = await CalculateSumAsync();
               Console.WriteLine(result);
           }
           catch (Exception ex)
           {
               Console.WriteLine(ex.Message);
           }
       }

    在这个例子中,CalculateSumAsync方法在计算总和的过程中抛出了一个异常。

    在Main方法中,使用try-catch块来捕获这个异常,并在控制台上输出异常消息。

    使用 Task.Exception 属性

    Task.Exception属性返回一个AggregateException,其中包含了Task中发生的所有异常。

    例如:

       Task<int> task = Task.Run(() =>
       {
           int sum = 0;
           for (int i = 0; i < 100; i++)
           {
               sum += i;
           }
           throw new Exception("An error occurred.");
           return sum;
       });
    
       try
       {
           task.Wait();
           int result = task.Result;
           Console.WriteLine(result);
       }
       catch (AggregateException ex)
       {
           foreach (var innerExceptionjavascript in ex.InnerExceptions)
           {
               Console.WriteLine(innerException.Message);
           }
       }

    在这个例子中,task.Wait()方法会阻塞当前线程,直到task完成。

    如果task中发生了异常,catch块将捕获AggregateException,并遍历其中的所有异常,在控制台上输出异常消息。

    Task 的延续

    使用 ContinueWith 方法

    ContinueWith方法用于在一个Task完成后执行另一个操作。

    例如:

       Task<int> task = Task.Run(() =>
       {
           int sum = 0;
           for (int i = 0; i < 100; i++)
           {
               sum += i;
           }
           return sum;
       });
    
       task.ContinueWith(t =>
       {
           Console.WriteLine(t.Result);
       });

    在这个例子中,task.ContinueWith方法在task完成后执行一个 lambda 表达式,该表达式输出task的结果。

    使用 await 关键字和异步方法

    也可以使用await关键字和异步方法来实现Task的延续。

    例如:

       async Task<int> CalculateSumAsync()
       {
           int sum = 0;
           for (int i = 0; i < 100; i++)
           {
               sum += i;
           }
           return sum;
       }
    
       async Task PrintResultAsync(int result)
       {
           Console.WriteLine(result);
       }
    
       async Task Main()
       {
           int result = await CalculateSumAsync();
           await PrintResultAsync(result);
       }

    在这个例子中,Main方法首先调用CalculateSumAsync方法,并使用await关键字等待该方法完成。然后,它调用PrintResultAsync方法,并使用await关键字等待该方法完成。

    这样,PrintResultAsync方法就作为CalculateSumAsync方法的延续执行。

    Task 的并行执行

    使用多个 Task

    可以同时启动多个Task,并等待它们全部完成。

    例如:

       Task&编程客栈lt;int> task1 = Task.Run(() =>
       {
           int sum = 0;
           for (int i = 0; i < 100; i++)
           {
               sum += i;
           }
           return sum;
       });
    
       Task<int> task2 = Task.Run(() =>
       {
          编程 int product = 1;
           for (int i = 1; i <= 10; i++)
           {
               product *= i;
           }
           return product;
       });
    
       Task.WaitAll(task1, task2);
       int sum = task1.Result;
       int product = task2.Result;
       Console.WriteLine(sum);
       Console.WriteLine(product);

    在这个例子中,同时启动了两个Task,一个计算从 0 到 99 的整数之和,另一个计算从 1 到 10 的整数之积。然后,使用Task.WaitAll方法等待这两个Task全部完成,并输出结果。

    使用 Task.WhenAll 方法

    Task.WhenAll方法返回一个Task,当所有传入的Task都完成时,这个Task才完成。

    例如:

       Task<int> task1 = Task.Run(() =>
       {
           int sum = 0;
           for (int i = 0; i < 100; i++)
           {
               sum += i;
           }
           return sum;
       });
    
       Task<int> task2 = Task.Run(() =>
       {
           int product = 1;
           for (int i = 1; i <= 10; i++)
           {
               product *= i;
           }
           return product;
       });
    
       Task<int[]> tasks = Task.WhenAll(task1, task2);
       int[] results = await tasks;
       int sum = results[0];
       int product = results[1];
       Console.WriteLine(sum);
       Console.WriteLine(product);

    在这个例子中,使用Task.WhenAll方法等待js两个Task全部完成,并返回一个包含两个Task结果的数组。然后,使用await关键字等待这个Task完成,并输出结果。

    总结

    Task是 C# 中一种强大的异步编程模型,它允许你在不阻塞主线程的情况下执行耗时的操作。

    通过使用Task,你可以提高应用程序的响应性和性能,同时保持代码的简洁和可读性。

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜