接上文 多线程编程学习笔记——任务并行库(一)html
接上文 多线程编程学习笔记——任务并行库(二)编程
接上文 多线程编程学习笔记——任务并行库(三)windows
8、 并行运行任务数组
本示例学习如何同时运行多个任务,而且当任务所有完成或其中一个完成时,如何高效的获得通知。多线程
1.示例代码异步
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ThreadPoolDemo { class Program { static void Main(string[] args) { Console.WriteLine(" 处理并行Task。。。。。"); var task1 = new Task<int>(() => RunTask("任务 1", 3)); var task2 = new Task<int>(() => RunTask("任务 2", 2)); var whenTaskAll = Task.WhenAll(task1, task2); whenTaskAll.ContinueWith(t => Console.WriteLine(" ——task1 结果值={0}---task2 结果值={1}",t.Result[0],t.Result[1]),
TaskContinuationOptions.OnlyOnRanToCompletion); task1.Start(); task2.Start(); Thread.Sleep(5000); Console.WriteLine(" ——————————————————————"); var tasks = new List<Task<int>>(); for (int i = 3; i < 10; i++) { int cnt = i; var task = new Task<int>(() => RunTask(string.Format("任务 {0}",cnt), cnt)); tasks.Add(task); task.Start(); } while(tasks.Count>0) { var completedTask = Task.WhenAny(tasks).Result; tasks.Remove(completedTask); Console.WriteLine(" ——一个task 完成任务—结果值={0}", completedTask.Result); } Thread.Sleep(7000); Console.Read(); } private static int RunTask(string name,int seconds) { Console.WriteLine("Task {0} 运行在线程={1}中,是否在线程池 :{2}",name,
Thread.CurrentThread.ManagedThreadId,Thread.CurrentThread.IsThreadPoolThread); Thread.Sleep(TimeSpan.FromSeconds(seconds)); return 20 * seconds; } } }
2。程序运行结果。以下图。post
当程序启动时,建立了两个任务(task1,task2),而后用task.whenall方法建立了第三个任务,这个任务会在全部任务完成以后运行。这个任务的结果提供了一个数组,第一个元素是第一个任务的结果,第二个元素是第二个任务的结果,以此类推。学习
而后咱们建立了一个任务列表,列表中有七个任务,而后使用task.whenany方法,等这一系列任务中的任何一个任务完成 ,就从列表中移除,并继续等待其余任务完成,直到列表为空。this
9、 使用taskScheduler配置任务的执行url
咱们学习任务调度程序,经过异步代码与UI进行交互。因此本示例是建立Windows应用程序。
taskScheduler是负责如何执行任务,默认状况下是把task放入线程池中的工做线程中。
1.在visual studio 中建立一个windowsForm个界面,名称为FormTPL 。这个界面中有同步,异步两个按钮。
2.程序界面以下图。
3.代码以下。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace ThreadTPLDemo { public partial class FormTPL : Form { public FormTPL() { InitializeComponent(); } private void buttonSync_Click(object sender, EventArgs e) { try { string result = RunTask().Result; textBoxMsg.Text = result; } catch (Exception ex) { textBoxMsg.Text = ex.Message; } } private void buttonAsync_Click(object sender, EventArgs e) { this.Cursor = Cursors.WaitCursor; Task<string> task = RunTask(); task.ContinueWith(t => { textBoxMsg.Text = t.Exception.InnerException.Message; this.Cursor = Cursors.Arrow; }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted,TaskScheduler.FromCurrentSynchronizationContext()); } private void buttonAsyncOk_Click(object sender, EventArgs e) { this.Cursor = Cursors.WaitCursor; Task<string> task = RunTask(TaskScheduler.FromCurrentSynchronizationContext()); task.ContinueWith(t =>this.Cursor=Cursors.Arrow, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.FromCurrentSynchronizationContext()); } private Task<string> RunTask() { return RunTask(TaskScheduler.Default); } private Task<string> RunTask(TaskScheduler tsched) { Task delay = Task.Delay(TimeSpan.FromSeconds(5)); return delay.ContinueWith(t => { string str = string.Format("Task 运行在线程={0},是不是在线程池中运行:{1}",Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread); textBoxMsg.Text = str; return str; },tsched); } } }
4。程序运行结果中会出现第一个问题,当点击同步按钮,执行程序时,整个应用 程序的用户界面假死,没法进行其余的任务操做。以下图。从图中2处能够看出“异步交互”按钮没法显示。
5. 解决同步执行界面会假死的问题,咱们使用异步执行的方式解决。
6. 第二个问题,并且当咱们从线程中直接访问UI界面中的控件时,会抛出异常。
7. 当咱们按第三个按钮,而后执行代码,程序正常运行,并获得结果。以下图。
最后,本人不建议使用taskScheduler来开发任务调度程序,建议使用Quartz.Net来开发任务调度程序。