C#中的Task使用方式

 更新时间:2024年12月16日 16:52:08   作者:呆呆小雅  
本文介绍了C#中的Task,这是一种异步编程模型,允许你在不阻塞主线程的情况下执行耗时的操作,文章详细介绍了如何创建、等待、处理异常、延续以及并行执行Task

前言

在 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 innerException 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<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方法等待两个Task全部完成,并返回一个包含两个Task结果的数组。然后,使用await关键字等待这个Task完成,并输出结果。

总结

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

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C#获取本地IP的四种方式示例详解

    C#获取本地IP的四种方式示例详解

    这篇文章主要介绍了C#获取本地IP的四种方式示例详解, 文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • C# SQLite库使用技巧

    C# SQLite库使用技巧

    SQLite是一个开源、免费的小型RDBMS(关系型数据库),能独立运行、无服务器、零配置、支持事物,用C实现,内存占用较小,支持绝大数的SQL92标准。下面跟随小编一起看下C# SQLite库使用
    2022-01-01
  • c# 执行动态编译的方法实例详解

    c# 执行动态编译的方法实例详解

    在C#中执行动态编译的一种方法是使用 CSharpCodeProvider 类,这篇文章主要介绍了c# 执行动态编译的方法,需要的朋友可以参考下
    2024-03-03
  • unity shader实现玻璃折射效果

    unity shader实现玻璃折射效果

    这篇文章主要为大家详细介绍了unity shader实现玻璃折射效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • WinForm实现基于BindingSource的方法扩展

    WinForm实现基于BindingSource的方法扩展

    这篇文章主要介绍了WinForm实现基于BindingSource的方法扩展,需要的朋友可以参考下
    2014-08-08
  • 基于C#实现网络爬虫 C#抓取网页Html源码

    基于C#实现网络爬虫 C#抓取网页Html源码

    这篇文章主要为大家详细介绍了基于C#实现网络爬虫的相关资料,即C#抓取网页Html源码,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • C#实现在Excel中插入和操作切片器

    C#实现在Excel中插入和操作切片器

    本文主要介绍了如何使用C#在Excel中插入和操作切片器,包括插入切片器到透视表和表格,修改切片器属性以及删除切片器,主要使用了Spire.XLSfor.NET库来实现这些功能,需要的朋友可以参考下
    2025-03-03
  • C# OpenCvSharp实现去除字母后面的杂线

    C# OpenCvSharp实现去除字母后面的杂线

    这篇文章主要为大家详细介绍了C#如何使用OpenCvSharp实现去除字母后面的杂线效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • c# 生成随机时间的小例子

    c# 生成随机时间的小例子

    这篇文章介绍了c# 生成随机时间的小例子,有需要的朋友可以参考一下
    2013-08-08
  • C#实现抓取和分析网页类实例

    C#实现抓取和分析网页类实例

    这篇文章主要介绍了C#实现抓取和分析网页类,实例分析了C#抓取及分析网页中文本及连接的相关使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-05-05

最新评论