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