C# 多线程八 任务Task的简单理解与运用二

目录

一.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的方法。

如果有不对的地方希望能指出来 感激不尽。

另外,不熟悉的代码一定要写一下加深记忆 只用看的记不了太久。

猜你喜欢

转载自blog.csdn.net/SmillCool/article/details/127281963