目录
上篇:
接着上篇,我们这篇主要说一下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的方法。
如果有不对的地方希望能指出来 感激不尽。
另外,不熟悉的代码一定要写一下加深记忆 只用看的记不了太久。