C# Task 包含 await ConfigureAwait CancellationTokenSource

本文主要是介绍C# Task 包含 await ConfigureAwait CancellationTokenSource,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • `Task`
    • 以下是 `Task` 类的一些关键特性和用法:
    • 以下是一些使用 `Task` 的示例:
    • 创建并启动一个任务
    • 使用 `await` 等待任务完成
    • 处理任务异常
    • 使用 `Task<TResult>` 获取结果
    • 取消任务
    • 总结
  • `await`
      • 暂停方法执行:
      • 非阻塞调用:
      • 任务结果获取:
      • 异常处理:
      • 同步上下文恢复:
      • 配置任务继续执行的线程:
      • 组合异步操作:
      • 简化异步编程:
    • 下面是一个使用 `await` 的简单示例:
  • `ConfigureAwait`
    • 使用场景
    • 语法
    • 参数
    • 示例
    • 总结
  • `CancellationTokenSource`
    • 下面是一个使用 `CancellationTokenSource` 的示例:
    • 总结
  • 个人理解
    • 例子如下
    • 运行结果如下

Task

C#中,TaskSystem.Threading.Tasks 命名空间中的一个类,它代表了异步操作 的执行。Task 类是异步编程模型的核心,它允许开发者编写非阻塞的代码,提高应用程序的响应性和性能。

以下是 Task 类的一些关键特性和用法:

  • 表示异步操作:Task 表示一个可能已经完成、正在运行或尚未开始的异步操作。

  • 返回值:Task<TResult>Task 的泛型版本,它表示一个异步操作,该操作将返回一个指定类型的结果。

  • 状态跟踪:Task 对象提供了属性来跟踪其状态,如 StatusIsCompletedIsFaulted 等。

  • 异常处理:如果异步操作中发生异常,Task 对象的 Exception 属性将包含异常信息。

  • 等待完成:可以使用 await 关键字或 Task.Wait()Task.Result 方法来等待 Task 完成。

  • 取消支持:Task 支持使用 CancellationToken 来取消操作。

  • 连续性:可以使用 ContinueWith 方法来安排在任务完成后执行的连续任务。

  • 并行执行:Task 可以与其他任务并行执行,使用 Task.WhenAllTask.WhenAny 来管理多个任务的完成。

以下是一些使用 Task 的示例:

创建并启动一个任务

// 创建并启动一个任务
Task task = Task.Run(() => 
{Console.WriteLine("Task is running on thread: " + Thread.CurrentThread.ManagedThreadId);
});
// 等待任务完成
task.Wait();

使用 await 等待任务完成

public async Task DoWorkAsync()
{await Task.Run(() => {// 模拟长时间运行的任务Thread.Sleep(1000);Console.WriteLine("Work is done.");});
}

处理任务异常

public async Task DoWorkWithExceptionAsync()
{try{await Task.Run(() => {throw new InvalidOperationException("Something went wrong!");});}catch (Exception ex){Console.WriteLine($"Caught an exception: {ex.Message}");}
}

使用 Task<TResult> 获取结果

public async Task<int> GetResultAsync()
{return await Task.Run(() => {// 模拟计算过程return 42;});
}

取消任务

public async Task CancelTaskAsync(CancellationToken cancellationToken)
{var task = Task.Run(() =>{while (!cancellationToken.IsCancellationRequested){// 模拟长时间运行的任务}}, cancellationToken);await Task.Delay(100); // 模拟一段时间后取消任务cancellationToken.Cancel();await task;
}

总结

Task 类是.NET异步编程的基础,它提供了一种简单而强大的方式来编写和组织异步代码。


await

C# 中,await 关键字用于异步编程,它有几个关键作用

暂停方法执行:

当编译器遇到一个 await 表达式时,它会暂停当前 async 方法的执行,直到被 await 的任务(TaskTask<T>)完成。

非阻塞调用:

await 允许程序在等待异步操作完成时继续执行其他代码。这意味着程序可以执行其他任务,而不是被阻塞等待异步操作的完成。

任务结果获取:

await 一个 Task<T> 时,它返回任务的结果。一旦任务完成,await 表达式的结果就是 Task<T> 的结果。

异常处理:

如果 await 的任务失败并抛出异常,异常会被传播到 await 调用的地方。如果 await 被包含在一个 try 块中,异常可以被捕获和处理。

同步上下文恢复:

await 表达式可以配置为在特定的同步上下文中继续执行(例如,UI 线程)。如果 await 表达式没有指定继续执行的上下文,它将恢复到调用它的原始上下文。

配置任务继续执行的线程:

使用 await 时,可以指定一个 TaskScheduler,来决定任务完成后在哪个线程上继续执行。

组合异步操作:

await 可以与 async 一起使用,创建更复杂的异步工作流,如链式调用多个异步方法。

简化异步编程:

使用 awaitasync 可以大大简化异步代码的编写,使异步代码看起来和同步代码类似,更容易理解和维护。

下面是一个使用 await 的简单示例:

using System;
using System.Threading.Tasks;class Program
{static async Task Main(){int result = await GetNumberAfterDelayAsync();Console.WriteLine(result);}static async Task<int> GetNumberAfterDelayAsync(){await Task.Delay(1000); // 模拟异步操作,延迟1秒return 42; // 返回结果}
}

在这个示例中,Main 方法使用 await 等待 GetNumberAfterDelayAsync 方法完成,并获取它返回的整数结果。await 使得 Main 方法可以非阻塞地等待异步操作的完成。


ConfigureAwait

C#中,ConfigureAwait 是一个方法,用于配置 await 操作是否继续在原始的同步上下文上执行,或者是否继续在不同的上下文上执行。这通常在异步编程中使用,特别是在使用 Taskasync 关键字时。

当你调用一个异步方法并使用 await 时,await 会返回一个 TaskTask<T> 对象。ConfigureAwaitTask 的一个扩展方法,允许你指定是否要捕获当前的同步上下文,并在继续执行异步操作时使用它。

使用场景

通常,当你在 UI 应用程序中使用异步方法时,你可能希望在 UI 线程上继续执行,以更新 UI 元素。默认情况下,await 会尝试捕获当前的同步上下文,并在异步操作完成后返回到这个上下文。但是,如果你在一个没有 UI 线程的上下文中使用 await,或者你希望避免不必要的上下文捕获,你可以使用 ConfigureAwait(false)

语法

await someTask.ConfigureAwait(false);

参数

false:指示 await 操作不需要捕获当前的同步上下文。这意味着当异步操作完成时,它不会尝试返回到原始的上下文,这可以提高性能,尤其是在没有 UI 线程或不需要 UI 更新的情况下。

true默认值):指示 await 操作应该捕获当前的同步上下文,并在异步操作完成后返回到这个上下文。这在需要更新 UI 或访问线程绑定对象时非常有用。

示例

public async Task SomeAsyncMethod()
{// 执行一些异步操作await SomeOtherAsyncMethod().ConfigureAwait(false);// 继续执行其他操作,这里不会捕获原始的同步上下文
}

总结

使用 ConfigureAwait(false) 可以提高性能,特别是在高并发的环境下,因为它避免了不必要的上下文切换。然而,你应该谨慎使用它,确保不会因此而违反线程安全或 UI 更新的需求


CancellationTokenSource

CancellationTokenSourceC#中的一个类,它提供了一种机制来发出取消请求。这个类与 CancellationToken 类一起使用,允许异步操作被取消。以下是 CancellationTokenSource 的一些关键特性和用法:

  • 创建: 你可以创建一个 CancellationTokenSource 的实例来开始一个取消操作。

  • 取消: 通过调用 CancellationTokenSourceCancel 方法,你可以发出取消请求。

  • 传播取消: CancellationTokenSource 可以传播取消请求到所有与之关联的 CancellationToken 对象。

  • 超时: 你可以设置一个超时时间,如果超时时间到了,取消请求会自动发出。

  • 链接: 你可以将多个 CancellationTokenSource 实例链接在一起,这样任何一个源发出取消请求,都会传播到所有链接的源。

下面是一个使用 CancellationTokenSource 的示例:

using System;
using System.Threading;
using System.Threading.Tasks;public class Program {public static void Main() {// 创建CancellationTokenSourcevar cts = new CancellationTokenSource();// 创建CancellationTokenCancellationToken token = cts.Token;// 启动一个异步任务Task task = Task.Run(() =>DoLongRunningOperation(token), token);// 模拟用户决定取消操作Console.WriteLine("按任意键取消操作...");Console.ReadKey();// 发出取消请求cts.Cancel();try {// 等待任务完成或抛出异常task.Wait();} catch (AggregateException ae) {// 处理取消异常foreach (var e in ae.InnerExceptions) {if (e is OperationCanceledException) {Console.WriteLine("操作已被取消。");}}}}private static void DoLongRunningOperation(CancellationToken cancellationToken) {for (int i = 0; i < 10; i++) {// 检查是否有取消请求cancellationToken.ThrowIfCancellationRequested();// 模拟长时间的工作Thread.Sleep(1000);Console.WriteLine($"执行步骤 {i + 1}");}}
}

总结

在这个示例中,我们创建了一个 CancellationTokenSource 并从它获取了一个 CancellationToken。然后,我们启动了一个异步任务 DoLongRunningOperation,并将 CancellationToken 传递给它。当用户按下任意键时,我们调用 Cancel 方法来发出取消请求。如果任务被取消,DoLongRunningOperation 方法中的 ThrowIfCancellationRequested 将抛出 OperationCanceledException 异常,我们捕获这个异常并处理它。


个人理解

对于一个aysnc修饰的方法,没有什么特殊的,调用也是正常的按顺序执行,但是,一旦你使用了await
就会出现这样的事情:

  • 首先,由于必须在有aysnc修饰的方法中使用await
  • 于是就说明的async的作用——将方法包装成状态机,
  • 所以在执行到await时:对于主线程来说,整个状态机(async修饰的方法)都会被挂起,然后这个方法会到其他线程执行,主线程继续执行该方法之后的语句,直到await后面的语句执行完毕,
  • 最后方法从被挂起的状态回归

例子如下

using System;
using System.Threading;
using System.Threading.Tasks;public class Program {public async static Task Main() {var cts = new CancellationTokenSource();CancellationToken token = cts.Token;try {DoLongRunningOperation(token);Console.WriteLine("Main  Thread:" + Environment.CurrentManagedThreadId);Thread.Sleep(500);cts.Cancel();} catch (TaskCanceledException ee) {Console.WriteLine(ee.Message);}Console.ReadKey();}private async static Task DoLongRunningOperation(CancellationToken cancellationToken) {int i = 1;while (!cancellationToken.IsCancellationRequested) {Console.WriteLine("DoLo  Thread:" + Environment.CurrentManagedThreadId);await Task.Delay(100);Console.WriteLine($"{i++}");}}
}

运行结果如下

DoLo  Thread:1
Main  Thread:1
1
DoLo  Thread:4
2
DoLo  Thread:4
3
DoLo  Thread:4
4
DoLo  Thread:4
5

这篇关于C# Task 包含 await ConfigureAwait CancellationTokenSource的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1059495

相关文章

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法

C#下Newtonsoft.Json的具体使用

《C#下Newtonsoft.Json的具体使用》Newtonsoft.Json是一个非常流行的C#JSON序列化和反序列化库,它可以方便地将C#对象转换为JSON格式,或者将JSON数据解析为C#对... 目录安装 Newtonsoft.json基本用法1. 序列化 C# 对象为 JSON2. 反序列化

C#文件复制异常:"未能找到文件"的解决方案与预防措施

《C#文件复制异常:未能找到文件的解决方案与预防措施》在C#开发中,文件操作是基础中的基础,但有时最基础的File.Copy()方法也会抛出令人困惑的异常,当targetFilePath设置为D:2... 目录一个看似简单的文件操作问题问题重现与错误分析错误代码示例错误信息根本原因分析全面解决方案1. 确保

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键

C#高效实现Word文档内容查找与替换的6种方法

《C#高效实现Word文档内容查找与替换的6种方法》在日常文档处理工作中,尤其是面对大型Word文档时,手动查找、替换文本往往既耗时又容易出错,本文整理了C#查找与替换Word内容的6种方法,大家可以... 目录环境准备方法一:查找文本并替换为新文本方法二:使用正则表达式查找并替换文本方法三:将文本替换为图

C#使用Spire.XLS快速生成多表格Excel文件

《C#使用Spire.XLS快速生成多表格Excel文件》在日常开发中,我们经常需要将业务数据导出为结构清晰的Excel文件,本文将手把手教你使用Spire.XLS这个强大的.NET组件,只需几行C#... 目录一、Spire.XLS核心优势清单1.1 性能碾压:从3秒到0.5秒的质变1.2 批量操作的优雅