我们知道,每个应用程序就是一个进程,一个进程有多个线程。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)); }
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对代码网的支持。如果你想了解更多相关内容请查看下面相关链接
发表评论