本文主要是介绍C# Task 包含 await ConfigureAwait CancellationTokenSource,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
- `Task`
- 以下是 `Task` 类的一些关键特性和用法:
- 以下是一些使用 `Task` 的示例:
- 创建并启动一个任务
- 使用 `await` 等待任务完成
- 处理任务异常
- 使用 `Task<TResult>` 获取结果
- 取消任务
- 总结
- `await`
- 暂停方法执行:
- 非阻塞调用:
- 任务结果获取:
- 异常处理:
- 同步上下文恢复:
- 配置任务继续执行的线程:
- 组合异步操作:
- 简化异步编程:
- 下面是一个使用 `await` 的简单示例:
- `ConfigureAwait`
- 使用场景
- 语法
- 参数
- 示例
- 总结
- `CancellationTokenSource`
- 下面是一个使用 `CancellationTokenSource` 的示例:
- 总结
- 个人理解
- 例子如下
- 运行结果如下
Task
在C#
中,Task
是 System.Threading.Tasks
命名空间中的一个类,它代表了异步操作 的执行。Task
类是异步编程模型的核心,它允许开发者编写非阻塞的代码,提高应用程序的响应性和性能。
以下是 Task
类的一些关键特性和用法:
-
表示异步操作:
Task
表示一个可能已经完成、正在运行或尚未开始的异步操作。 -
返回值:
Task<TResult>
是Task
的泛型版本,它表示一个异步操作,该操作将返回一个指定类型的结果。 -
状态跟踪:
Task
对象提供了属性来跟踪其状态,如Status
、IsCompleted
、IsFaulted
等。 -
异常处理:如果异步操作中发生异常,
Task
对象的Exception
属性将包含异常信息。 -
等待完成:可以使用
await
关键字或Task.Wait()
、Task.Result
方法来等待Task
完成。 -
取消支持:
Task
支持使用CancellationToken
来取消操作。 -
连续性:可以使用
ContinueWith
方法来安排在任务完成后执行的连续任务。 -
并行执行:
Task
可以与其他任务并行执行,使用Task.WhenAll
或Task.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
的任务(Task
或Task<T>
)完成。
非阻塞调用:
await
允许程序在等待异步操作完成时继续执行其他代码。这意味着程序可以执行其他任务,而不是被阻塞等待异步操作的完成。
任务结果获取:
当 await
一个 Task<T>
时,它返回任务的结果。一旦任务完成,await
表达式的结果就是 Task<T>
的结果。
异常处理:
如果 await
的任务失败并抛出异常,异常会被传播到 await
调用的地方。如果 await
被包含在一个 try
块中,异常可以被捕获和处理。
同步上下文恢复:
await
表达式可以配置为在特定的同步上下文中继续执行(例如,UI
线程)。如果 await
表达式没有指定继续执行的上下文,它将恢复到调用它的原始上下文。
配置任务继续执行的线程:
使用 await
时,可以指定一个 TaskScheduler
,来决定任务完成后在哪个线程上继续执行。
组合异步操作:
await
可以与 async
一起使用,创建更复杂的异步工作流,如链式调用多个异步方法。
简化异步编程:
使用 await
和 async
可以大大简化异步代码的编写,使异步代码看起来和同步代码类似,更容易理解和维护。
下面是一个使用 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
操作是否继续在原始的同步上下文上执行,或者是否继续在不同的上下文上执行。这通常在异步编程中使用,特别是在使用 Task
和 async
关键字时。
当你调用一个异步方法并使用 await
时,await
会返回一个 Task
或 Task<T>
对象。ConfigureAwait
是 Task
的一个扩展方法,允许你指定是否要捕获当前的同步上下文,并在继续执行异步操作时使用它。
使用场景
通常,当你在 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
CancellationTokenSource
是C#
中的一个类,它提供了一种机制来发出取消请求。这个类与 CancellationToken
类一起使用,允许异步操作被取消。以下是 CancellationTokenSource
的一些关键特性和用法:
-
创建: 你可以创建一个
CancellationTokenSource
的实例来开始一个取消操作。 -
取消: 通过调用
CancellationTokenSource
的Cancel
方法,你可以发出取消请求。 -
传播取消:
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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!