目录
一.Task
1.AsyncState
2.CompletedTask
3.CreationOptions
4.CurrentId
5.Exception
6.Factory
7.Id
8.IsCanceled
9.IsCompleted
10.IsFaulted
11.Status
二.Task<TResult>
1.Result
上篇:
C# 多线程七 任务Task的简单理解与运用一
接着上篇,我们这篇主要说一下Task的属性
前言:Task的属性说明基本都是从Task.Exception 属性 (System.Threading.Tasks) | Microsoft Learn拷贝下来的,只是加了自己的理解和测试代码以及打印来供大家更好的理解。
一.Task
1.AsyncState
获取在创建 Task 时提供的状态对象,如果未提供,则为 null。
自己的测试:
1.Task task=new Task(); task.Start();调用模式下
获取以下几种构造方法传入的state的值
public Task(Action<object> action, object state);
public Task(Action<object> action, object state, CancellationToken cancellationToken);
public Task(Action<object> action, object state, TaskCreationOptions creationOptions);public Task(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions);
测试代码:
using(CancellationTokenSource source = new CancellationTokenSource()) {Task task = new Task((obj) => {Console.WriteLine("开始执行task任务:" + obj);}, (object)"xxx", source.Token, TaskCreationOptions.None);Console.WriteLine(task.AsyncState);task.Start();}
打印:

2.Task.Factory.StartNew();调用模式下
获取以下方法传入的state的值
public Task StartNew(Action<object> action, object state, CancellationToken cancellationToken);
public Task StartNew(Action<object> action, object state, TaskCreationOptions creationOptions);
public Task StartNew(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler);
public Task<TResult> StartNew<TResult>(Func<object, TResult> function, object state);
public Task<TResult> StartNew<TResult>(Func<object, TResult> function, object state, CancellationToken cancellationToken);
public Task<TResult> StartNew<TResult>(Func<object, TResult> function, object state, TaskCreationOptions creationOptions);
public Task<TResult> StartNew<TResult>(Func<object, TResult> function, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler);
public Task StartNew(Action<object> action, object state);
测试代码:
using(CancellationTokenSource source = new CancellationTokenSource()) {Task task1 = Task.Factory.StartNew((obj) => {Console.WriteLine("开始执行task1任务:" + obj);}, (object)"zzz", source.Token);Console.WriteLine(task1.AsyncState);}
打印:

2.CompletedTask
获取一个已成功完成的任务。
这个属性 我整了好久才懂 首先CompletedTask取到的不是你当前完成后的Task,他会给你创建一个独立Task,另外使用CompletedTask和await async关键字依然是单线程。
两个例子
1.CompletedTask取到的不是你当前完成后的Task
代码:
using(CancellationTokenSource source = new CancellationTokenSource()) {for(int i = 0; i < 100; i++) {Task.Run(() => {Console.WriteLine($"开始执行task{i}任务 taskID :{Task.CurrentId}");});}Thread.Sleep(1000);Console.WriteLine("获取一个完成任务ID:" + Task.CompletedTask.Id);}
打印:

2.CompletedTask和await async关键字依然是单线程
代码:
static async void DoSomething() {Task task = Task.Run(() => {Console.WriteLine("开始执行task");});await task;Console.WriteLine("DoSomething 获取当前执行线程" + Thread.CurrentThread.ManagedThreadId);}static async void DoSomething1() {await Task.CompletedTask;Console.WriteLine("DoSomething1 获取当前执行线程" + Thread.CurrentThread.ManagedThreadId);}static void Main(string[] args) {DoSomething();DoSomething1();Console.WriteLine("Main 获取当前执行线程" + Thread.CurrentThread.ManagedThreadId);Console.ReadLine();
}
打印:

3.CreationOptions
获取用于创建此任务的 TaskCreationOptions。
和AsyncState类似只不过一个是获取object state 一个是获取 TaskCreationOptions
4.CurrentId
返回当前正在执行 Task 的 ID。
在当前task执行中调用 外部调用使用Id
代码:
Task task1 = Task.Factory.StartNew((obj) => {Console.WriteLine("开始执行task1任务:" + obj + " ID :" + Task.CurrentId);}, (object)"zzz", source.Token);
5.Exception
获取 AggregateException导致 的 提前结束的 Task。 如果 Task 成功完成或尚未引发任何异常,这将返回 null。
代码:
using(CancellationTokenSource source = new CancellationTokenSource()) {Task task1 = new Task((obj) => {int[] num = new int[2];Task task = Task.Factory.StartNew(() => {Console.WriteLine("开始执行task1子任务task:" + Task.CurrentId + num[3]);}, source.Token, TaskCreationOptions.AttachedToParent, TaskScheduler.Current);Console.WriteLine("开始执行task1任务:" + obj + " ID :" + Task.CurrentId);}, (object)"zzz", source.Token);task1.Start();Thread.Sleep(3000);Console.WriteLine(" 未经处理异常 : " + task1.Exception);Console.WriteLine(" 由于未经处理异常的原因 : " + task1.IsFaulted);}
打印:

6.Factory
提供对用于创建和配置 Task 和 Task<TResult> 实例的工厂方法的访问。
7.Id
获取此 Task 实例的 ID。
在Task外部使用
代码:
Task task1 = Task.Factory.StartNew((obj) => {Console.WriteLine("开始执行task1任务:" + obj + " ID :" + Task.CurrentId);}, (object)"zzz", source.Token);Console.WriteLine("task1ID: " + task1.Id);
8.IsCanceled
获取此 Task 实例是否由于被取消的原因而已完成执行。
代码:
using(CancellationTokenSource source = new CancellationTokenSource()) {Task task1 = Task.Factory.StartNew((obj) => {Console.WriteLine("开始执行task1任务:" + obj + " ID :" + Task.CurrentId);}, (object)"zzz", source.Token);source.Cancel();//Thread.Sleep(1000);Console.WriteLine(" 是否被取消结束的任务 : " + task1.IsCanceled);}
打印:

此时明明已经取消了为什么会打印false呢?因为Task还没开始执行 就去检测了
修改:
using(CancellationTokenSource source = new CancellationTokenSource()) {Task task1 = Task.Factory.StartNew((obj) => {Console.WriteLine("开始执行task1任务:" + obj + " ID :" + Task.CurrentId);}, (object)"zzz", source.Token);source.Cancel();Thread.Sleep(1000);Console.WriteLine(" 是否被取消结束的任务 : " + task1.IsCanceled);}
打印:

9.IsCompleted
获取一个值,它表示是否已完成任务。
代码:
using(CancellationTokenSource source = new CancellationTokenSource()) {Task task1 = Task.Factory.StartNew((obj) => {Console.WriteLine("开始执行task1任务:" + obj + " ID :" + Task.CurrentId);}, (object)"zzz", source.Token);source.Cancel();Thread.Sleep(1000);Console.WriteLine(" 是否被取消结束的任务 : " + task1.IsCanceled);Console.WriteLine(" 是否已经完成任务 : " + task1.IsCompleted);}
打印:

由此可见 就算是取消了任务的执行 IsCompleted也会返回true表示任务完成
10.IsFaulted
获取 Task 是否由于未经处理异常的原因而完成。
Exception中已有测试 不再赘述
11.Status
获取此任务的 TaskStatus。
代码:
using(CancellationTokenSource source = new CancellationTokenSource()) {Task task1 = new Task((obj) => {Console.WriteLine("开始执行task1任务:" + obj + " ID :" + Task.CurrentId);}, (object)"zzz", source.Token);Console.WriteLine("task1任务状态1:" + task1.Status);task1.Start();Thread.Sleep(3000);Console.WriteLine("task1任务状态2:" + task1.Status);}
打印:

二.Task<TResult>
1.Result
获取此 Task<TResult> 的结果值。
会阻塞线程
代码:
Task<string> task = Task.Factory.StartNew<string>(() => {Thread.Sleep(1000);Console.WriteLine("开始执行task");return "返回值";});Console.WriteLine(task.Result);Console.WriteLine("执行主线程");Console.ReadLine();
打印:

Task的属性到此就写完了,下篇将接着写Task的方法。
如果有不对的地方希望能指出来 感激不尽。
另外,不熟悉的代码一定要写一下加深记忆 只用看的记不了太久。

















