您的位置:首页技术文章
文章详情页

.Net中Task Parallel Library的基本用法

【字号: 日期:2022-06-08 16:47:04浏览:25作者:猪猪

我们知道,每个应用程序就是一个进程,一个进程有多个线程。Task Parallel Library为我们的异步编程、多线程编程提供了强有力的支持,它允许一个主线程运行的同时,另外的一些线程或Task也同时运行。本篇体验基本用法。

基本用法

Taks的构造函数接收的类型是Action,也就是一个委托。

static void Main(string[] args){    var t1 = new Task(() =>    {Console.WriteLine("任务1开始");Thread.Sleep(1000);Console.WriteLine("任务1结束");    });    t1.Start();    Console.ReadKey();}

如果把方法放到外面。

static void Main(string[] args){    var t1 = new Task(() => DoSth(1,2000));    t1.Start();    Console.ReadKey();}static void DoSth(int id, int sleepTime){    Console.WriteLine("任务{0}开始",id);    Thread.Sleep(sleepTime);    Console.WriteLine("任务{0}结束",id);}

如果有多个Task同时执行。

static void Main(string[] args){    var t1 = new Task(() => DoSth(1,2000));    t1.Start();    var t2 = new Task(() => DoSth(2, 1500));    t2.Start();    var t3 = new Task(() => DoSth(3, 3000));    t3.Start();    Console.ReadKey();}

如果有很多Task,每个Task手动启动的话很费事,Task Parallel Library为我们准备了Task工厂。

static void Main(string[] args){    var t1 = Task.Factory.StartNew(() => DoSth(1, 2000));    var t2 = Task.Factory.StartNew(() => DoSth(2, 1500));    var t3 = Task.Factory.StartNew(() => DoSth(3, 3000));    Console.ReadKey();}

如果我们想在一个任务结束之后立即执行某个任务,可以使用ContinueWith方法。

static void Main(string[] args){    var t1 = Task.Factory.StartNew(() => DoSth(1, 2000)).ContinueWith((pre)=> DoOtherThing(4,2000));     var t2 = Task.Factory.StartNew(() => DoSth(2, 1500));    var t3 = Task.Factory.StartNew(() => DoSth(3, 3000));    Console.ReadKey();}static void DoSth(int id, int sleepTime){    Console.WriteLine("任务{0}开始",id);    Thread.Sleep(sleepTime);    Console.WriteLine("任务{0}结束",id);}static void DoOtherThing(int id, int sleepTime){    Console.WriteLine("其他任务{0}开始", id);    Thread.Sleep(sleepTime);    Console.WriteLine("其他任务{0}结束", id);}

如果希望等待所有的Task执行完毕,使用WaitAll方法。

static void Main(string[] args){    var t1 = Task.Factory.StartNew(() => DoSth(1, 2000));    var t2 = Task.Factory.StartNew(() => DoSth(2, 1500));    var t3 = Task.Factory.StartNew(() => DoSth(3, 3000));    var taskList = new List<Task> {t1, t2, t3};    Task.WaitAll(taskList.ToArray());    Console.WriteLine("我是在所有Task执行完毕后才执行的");    Console.ReadKey();}

如果想手动取消结束某个Task,需要为方法带上CancellationToken类型参数。

static void Main(string[] args){    var source = new CancellationTokenSource();    try    {var t1 =    Task.Factory.StartNew(() => DoSth(1, 1000, source.Token)).ContinueWith((pre) => DoOtherThing(2, 2000));source.Cancel();    }    catch (Exception ex)    {Console.WriteLine(ex.GetType());    }    Console.WriteLine("haha");    Console.ReadKey();}static void DoSth(int id, int sleepTime, CancellationToken token){    if (token.IsCancellationRequested)    {Console.WriteLine("任务被取消");token.ThrowIfCancellationRequested();    }        Console.WriteLine("任务{0}开始",id);    Thread.Sleep(sleepTime);    Console.WriteLine("任务{0}结束",id);}static void DoOtherThing(int id, int sleepTime){    Console.WriteLine("其他任务{0}开始", id);    Thread.Sleep(sleepTime);    Console.WriteLine("其他任务{0}结束", id);}

如何从Task从获取方法的返回结果呢?

static void Main(string[] args){    Console.WriteLine("开始计算");    Task<int> t = Task.Factory.StartNew(() => Sum(1, 2));    Console.WriteLine("等待结果");    Console.WriteLine(t.Result);    Console.ReadKey();}static int Sum(int a, int b){    return a + b;}

后面一个Task获取前面一个Task的返回值。

static void Main(string[] args){    Task<string> firstTask = Task.Factory.StartNew<string>(() =>    {Console.WriteLine("第一个任务开始");return "hi from the one";    });    Task secondTask = firstTask.ContinueWith((prevoursTask) =>    {Console.WriteLine("这里是第二个任务,获取到第一个任务的返回值是{0}",prevoursTask.Result,TaskContinuationOptions.OnlyOnRanToCompletion);    });    secondTask.Wait();    Console.ReadKey();}

等待所有Task完成。

static void Main(string[] args){   var t1 =  Task.Factory.StartNew(() =>    {Console.WriteLine("第一个任务");Thread.Sleep(1000);    });    var t2 = Task.Factory.StartNew(() =>    {Console.WriteLine("第二个任务");Thread.Sleep(1000);    });    var taskList = new List<Task> {t1, t2};    Task.Factory.ContinueWhenAll(taskList.ToArray(), (t) => { Console.WriteLine("所有任务完成我就出来"); });    Console.ReadKey();}

如果是嵌套Task。

static void Main(string[] args){    Task.Factory.StartNew(() =>    {Task child = Task.Factory.StartNew(() =>{    Console.WriteLine("我是子任务");}, TaskCreationOptions.AttachedToParent);    }).Wait();    Console.ReadKey();}

启动Task的几种方式

1、通过Task.Factory.StartNew方法。

static void Main(string[] args){    Task.Factory.StartNew(() => SaySth("hello"));    Console.ReadKey();}static void SaySth(string msg){    Console.WriteLine(msg);}

2、通过Task的Start实例方法

static void Main(string[] args){    var t = new Task(() => SaySth("hello"));    t.Start();    Console.ReadKey();}

或者干脆用委托。

static void Main(string[] args){    Task t = new Task(delegate {SaySth("hello");});    t.Start();    Console.ReadKey();}

3、Task的静态方法Run

static void Main(string[] args){    Task t = Task.Run(() => SaySth("hello"));    Console.ReadKey();}static void SaySth(string msg){    Console.WriteLine(msg);}  

一个例子

比如说要下载某个页面,在保持当前UI界面无影响的情况下,使用Task在后台启动任务下载某个页面。

static void Main(string[] args){    Console.WriteLine("界面内容");    Task<string> r = DownloadAsync("http://www.baidu.com");    while (!r.IsCompleted)    {Console.Write(".");Thread.Sleep(250);    }    Console.WriteLine(r.Result);    Console.ReadKey();}private static string DownloadWebPage(string url){    WebRequest request = WebRequest.Create(url);    WebResponse response = request.GetResponse();    var reader = new StreamReader(response.GetResponseStream());    return reader.ReadToEnd();}private static Task<string> DownloadAsync(string url){    return Task.Factory.StartNew(() => DownloadWebPage(url));}

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接

标签: ASP.NET
相关文章: