ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

多线程--Task

2022-07-23 12:02:10  阅读:242  来源: 互联网

标签:CancellationToken Task -- 创建 指定 任务 完成 多线程


1.1 基本介绍

Task被称为多线程的最佳实践,

(1)Task线程全是线程池线程

(2)提供了丰富的API ,非常适合实践

 

1.2 创建和执行Task

 

       Task 可以通过多种方式创建实例。 从 .NET Framework 4.5 开始,最常见的方法是调用静态Run方法。 此方法 Run 提供了一种使用默认值启动任务的简单方法,

而无需其他参数。

 

 public static async Task Main()
        {
            await Task.Run(() => {
                // Just loop.
                int ctr = 0;
                for (ctr = 0; ctr <= 1000000; ctr++)
                { }
                Console.WriteLine("Finished {0} loop iterations",
                                  ctr);
            });
        }

 

   一种替代方法,也是在 .NET Framework 4 中启动任务的最常见方法是静态TaskFactory.StartNew方法。 该 Task.Factory 属性返回对象 TaskFactory 。 使用此方法的 TaskFactory.StartNew 重载可以指定参数以传递给任务创建选项和任务计划程序。

 

 public static void Main()
   {
      Task t = Task.Factory.StartNew( () => {
                                  // Just loop.
                                  int ctr = 0;
                                  for (ctr = 0; ctr <= 1000000; ctr++)
                                  {}
                                  Console.WriteLine("Finished {0} loop iterations",
                                                    ctr);
                               } );
      t.Wait();
   }

 

1.3 等待一个或多个任务完成

   由于任务通常在线程池线程上异步运行,因此在实例化任务后,创建和启动任务的线程会继续执行。 在某些情况下,当调用线程是主应用程序线程时,应用可能会在任务实际开始执行之前终止。 其他情况下,应用程序的逻辑可能要求调用线程仅在一个或多个任务完成执行时才继续执行。 可以通过调用 Wait 方法等待一个或多个任务完成来同步调用线程的执行及其启动的异步任务。

   若要等待单个任务完成,可以调用其 Task.Wait 方法。 对方法的 Wait 调用会阻止调用线程,直到单个类实例完成执行。

   

static void Main(string[] args)
        {
            Task task1 = Task.Run(()=>Thread.Sleep(3000));
            Console.WriteLine($"task1状态:{task1.Status}");
            try
            {
                task1.Wait();
                Console.WriteLine($"task1状态:{task1.Status}");
                Console.WriteLine("我是主线程");
            }
            catch (AggregateException ex)
            {
                Console.WriteLine($"task1发生异常,{ex.Message}");
            }
            Console.ReadLine();
        }

 

 

 

 在某些情况下,你可能希望等待一系列执行任务中的第一个完成,但不关心它所在的任务。 为此,可以调用方法的 Task.WaitAny 重载之一。

 

 static void Main(string[] args)
        {
            var tasks = new Task[3];
            var random = new Random();
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Run(()=>Thread.Sleep(random.Next(500,3000)));
            }
            try
            {
                int index = Task.WaitAny(tasks);
                Console.WriteLine($"任务{tasks[index].Id} 第一个完成.\n");
                Console.WriteLine("所有任务状态:");
                foreach (var t in tasks)
                {
                    Console.WriteLine($"任务{t.Id}:{t.Status}");
                }
            }
            catch (AggregateException ex)
            {
                Console.WriteLine($"发生异常,{ex.Message}");
            }
            Console.ReadLine();
        }

 

 

 

 

还可以通过调用 WaitAll 方法等待所有一系列任务完成。 以下示例创建 10 个任务,等待所有 10 个任务完成,然后显示其状态。

 

 public static void Main()
        {
            Task[] tasks = new Task[10];
            for (int i = 0; i < 10; i++)
            {
                tasks[i] = Task.Run(() => Thread.Sleep(2000));
            }
            try
            {
                Task.WaitAll(tasks);
            }
            catch (AggregateException ex)
            {
                Console.WriteLine("发生异常: ");
                foreach (var innerex in ex.Flatten().InnerExceptions)
                    Console.WriteLine("   {0}", innerex.Message);
            }

            Console.WriteLine("Status of completed tasks:");
            foreach (var t in tasks)
                Console.WriteLine("   任务{0}: {1}", t.Id, t.Status);
        }

 

经常使用的四个方法:

Task.WaitAny(tasks);
Task.WaitAll(tasks);
Task.WhenAny(tasks);
Task.WhenAll(tasks);

 

 

 

 

1.4 所有方法

ConfigureAwait(Boolean)

配置用于等待此 Task的 awaiter。

ContinueWith(Action<Task,Object>, Object)

创建一个在目标 Task 完成时接收调用方提供的状态信息并执行的延续任务。

ContinueWith(Action<Task,Object>, Object, CancellationToken)

创建一个在目标 Task 完成时接收调用方提供的状态信息和取消标记,并以异步方式执行的延续任务。

ContinueWith(Action<Task,Object>, Object, CancellationToken, TaskContinuationOptions, TaskScheduler)

创建一个在目标 Task 完成时接收调用方提供的状态信息和取消标记并执行的延续任务。 延续任务根据一组指定的条件执行,并使用指定的计划程序。

ContinueWith(Action<Task,Object>, Object, TaskContinuationOptions)

创建一个在目标 Task 完成时接收调用方提供的状态信息并执行的延续任务。 延续任务根据一组指定的条件执行。

ContinueWith(Action<Task,Object>, Object, TaskScheduler)

创建一个在目标 Task 完成时接收调用方提供的状态信息并以异步方式执行的延续任务。 延续任务使用指定计划程序。

ContinueWith(Action<Task>)

创建一个在目标 Task 完成时异步执行的延续任务。

ContinueWith(Action<Task>, CancellationToken)

创建一个在目标 Task 完成时可接收取消标记并以异步方式执行的延续任务。

ContinueWith(Action<Task>, CancellationToken, TaskContinuationOptions, TaskScheduler)

创建一个在目标任务完成时按照指定的 TaskContinuationOptions 执行的延续任务。 延续任务会收到一个取消标记,并使用指定的计划程序。

ContinueWith(Action<Task>, TaskContinuationOptions)

创建一个在目标任务完成时按照指定的 TaskContinuationOptions 执行的延续任务。

ContinueWith(Action<Task>, TaskScheduler)

创建一个在目标 Task 完成时异步执行的延续任务。 延续任务使用指定计划程序。

ContinueWith<TResult>(Func<Task,Object,TResult>, Object)

创建一个在目标 Task 完成并返回一个值时接收调用方提供的状态信息并以异步方式执行的延续任务。

ContinueWith<TResult>(Func<Task,Object,TResult>, Object, CancellationToken)

创建一个在目标 Task 完成时异步执行并返回一个值的延续任务。 延续任务接收调用方提供的状态信息和取消标记。

ContinueWith<TResult>(Func<Task,Object,TResult>, Object, CancellationToken, TaskContinuationOptions, TaskScheduler)

创建一个在目标 Task 完成并返回一个值时根据指定的任务延续选项执行的延续任务。 延续任务接收调用方提供的状态信息和取消标记,并使用指定的计划程序。

ContinueWith<TResult>(Func<Task,Object,TResult>, Object, TaskContinuationOptions)

创建一个在目标 Task 完成时根据指定的任务延续选项执行的延续任务。 延续任务接收调用方提供的状态信息。

ContinueWith<TResult>(Func<Task,Object,TResult>, Object, TaskScheduler)

创建一个在目标 Task 完成时异步执行的延续任务。 延续任务接收调用方提供的状态信息,并使用指定的计划程序。

ContinueWith<TResult>(Func<Task,TResult>)

创建一个在目标 Task<TResult> 完成时异步执行并返回一个值的延续任务。

ContinueWith<TResult>(Func<Task,TResult>, CancellationToken)

创建一个在目标 Task 完成时异步执行并返回一个值的延续任务。 延续任务收到取消标记。

ContinueWith<TResult>(Func<Task,TResult>, CancellationToken, TaskContinuationOptions, TaskScheduler)

创建一个按照指定延续任务选项执行并返回一个值的延续任务。 延续任务被传入一个取消标记,并使用指定的计划程序。

ContinueWith<TResult>(Func<Task,TResult>, TaskContinuationOptions)

创建一个按照指定延续任务选项执行并返回一个值的延续任务。

ContinueWith<TResult>(Func<Task,TResult>, TaskScheduler)

创建一个在目标 Task 完成时异步执行并返回一个值的延续任务。 延续任务使用指定计划程序。

Delay(Int32)

创建一个在指定的毫秒数后完成的任务。

Delay(Int32, CancellationToken)

创建一个在指定的毫秒数后完成的可取消任务。

Delay(TimeSpan)

创建一个在指定的时间间隔后完成的任务。

Delay(TimeSpan, CancellationToken)

创建一个在指定的时间间隔后完成的可取消任务。

Dispose()

释放 Task 类的当前实例所使用的所有资源。

Dispose(Boolean)

释放 Task,同时释放其所有非托管资源。

Equals(Object)

确定指定对象是否等于当前对象。

(继承自 Object)
FromCanceled(CancellationToken)

创建 Task,它因指定的取消标记进行的取消操作而完成。

FromCanceled<TResult>(CancellationToken)

创建 Task<TResult>,它因指定的取消标记进行的取消操作而完成。

FromException(Exception)

创建 Task,它在完成后出现指定的异常。

FromException<TResult>(Exception)

创建 Task<TResult>,它在完成后出现指定的异常。

FromResult<TResult>(TResult)

创建指定结果的、成功完成的 Task<TResult>

GetAwaiter()

获取用于等待此 Task 的 awaiter。

GetHashCode()

作为默认哈希函数。

(继承自 Object)
GetType()

获取当前实例的 Type

(继承自 Object)
MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
Run(Action)

将在线程池上运行的指定工作排队,并返回代表该工作的 Task 对象。

Run(Action, CancellationToken)

将在线程池上运行的指定工作排队,并返回代表该工作的 Task 对象。 可使用取消标记来取消工作(如果尚未启动)。

Run(Func<Task>)

将在线程池上运行的指定工作排队,并返回 function 所返回的任务的代理项。

Run(Func<Task>, CancellationToken)

将在线程池上运行的指定工作排队,并返回 function 所返回的任务的代理项。 可使用取消标记来取消工作(如果尚未启动)。

Run<TResult>(Func<Task<TResult>>)

将指定的工作排成队列在线程池上运行,并返回由 function 返回的 Task(TResult) 的代理。 可使用取消标记来取消工作(如果尚未启动)。

Run<TResult>(Func<Task<TResult>>, CancellationToken)

将指定的工作排成队列在线程池上运行,并返回由 function 返回的 Task(TResult) 的代理。

Run<TResult>(Func<TResult>)

将在线程池上运行的指定工作排队,并返回代表该工作的 Task<TResult> 对象。 可使用取消标记来取消工作(如果尚未启动)。

Run<TResult>(Func<TResult>, CancellationToken)

将在线程池上运行的指定工作排队,并返回代表该工作的 Task(TResult) 对象。

RunSynchronously()

对当前的 Task 同步运行 TaskScheduler

RunSynchronously(TaskScheduler)

对提供的 Task 同步运行 TaskScheduler

Start()

启动 Task,并将它安排到当前的 TaskScheduler 中执行。

Start(TaskScheduler)

启动 Task,并将它安排到指定的 TaskScheduler 中执行。

ToString()

返回表示当前对象的字符串。

(继承自 Object)
Wait()

等待 Task 完成执行过程。

Wait(CancellationToken)

等待 Task 完成执行过程。 如果在任务完成之前取消标记已取消,等待将终止。

Wait(Int32)

等待 Task 在指定的毫秒数内完成执行。

Wait(Int32, CancellationToken)

等待 Task 完成执行过程。 如果在任务完成之前超时间隔结束或取消标记已取消,等待将终止。

Wait(TimeSpan)

等待 Task 在指定的时间间隔内完成执行。

WaitAll(Task[])

等待提供的所有 Task 对象完成执行过程。

WaitAll(Task[], CancellationToken)

等待提供的所有 Task 对象完成执行过程(除非取消等待)。

WaitAll(Task[], Int32)

等待所有提供的 Task 在指定的毫秒数内完成执行。

WaitAll(Task[], Int32, CancellationToken)

等待提供的所有 Task 对象在指定的毫秒数内完成执行,或等到取消等待。

WaitAll(Task[], TimeSpan)

等待所有提供的可取消 Task 对象在指定的时间间隔内完成执行。

WaitAny(Task[])

等待提供的任一 Task 对象完成执行过程。

WaitAny(Task[], CancellationToken)

等待提供的任何 Task 对象完成执行过程(除非取消等待)。

WaitAny(Task[], Int32)

等待任何提供的 Task 对象在指定的毫秒数内完成执行。

WaitAny(Task[], Int32, CancellationToken)

等待提供的任何 Task 对象在指定的毫秒数内完成执行,或等到取消标记取消。

WaitAny(Task[], TimeSpan)

等待任何提供的 Task 对象在指定的时间间隔内完成执行。

WhenAll(IEnumerable<Task>)

创建一个任务,该任务将在可枚举集合中的所有 Task 对象都已完成时完成。

WhenAll(Task[])

创建一个任务,该任务将在数组中的所有 Task 对象都已完成时完成。

WhenAll<TResult>(IEnumerable<Task<TResult>>)

创建一个任务,该任务将在可枚举集合中的所有 Task<TResult> 对象都已完成时完成。

WhenAll<TResult>(Task<TResult>[])

创建一个任务,该任务将在数组中的所有 Task<TResult> 对象都已完成时完成。

WhenAny(IEnumerable<Task>)

任何提供的任务已完成时,创建将完成的任务。

WhenAny(Task[])

任何提供的任务已完成时,创建将完成的任务。

WhenAny<TResult>(IEnumerable<Task<TResult>>)

任何提供的任务已完成时,创建将完成的任务。

WhenAny<TResult>(Task<TResult>[])

任何提供的任务已完成时,创建将完成的任务。

Yield()

创建异步产生当前上下文的等待任务。

 

 

 

参考:https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.tasks?view=netframework-4.8

 

           https://www.bilibili.com/medialist/play/ml1297569058/BV1Yv411A73j?spm_id_from=333.999.0.0&oid=250144381&otype=2

标签:CancellationToken,Task,--,创建,指定,任务,完成,多线程
来源: https://www.cnblogs.com/hobelee/p/16511685.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有