当前位置: 代码网 > it编程>编程语言>Asp.net > .Net中Task Parallel Library的基本用法

.Net中Task Parallel Library的基本用法

2024年05月15日 Asp.net 我要评论
我们知道,每个应用程序就是一个进程,一个进程有多个线程。task parallel library为我们的异步编程、多线程编程提供了强有力的支持,它允许一个主线程运行的同时,另外的一些线程或task也

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

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

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com