.Net中Task Parallel Library的基本用法(.net framework 3.5有必要装吗)满满干货

随心笔谈12个月前发布 admin
98 0



我们知道,每个应用程序就是一个进程,一个进程有多个线程。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();
}

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?Core在Task中使用IServiceProvider的问题解析.Net通过TaskFactory.FromAsync简化APM.NET中的async和await关键字使用及Task异步调用实例.Net中Task Parallel Library的进阶用法

© 版权声明

相关文章