当前位置: 移动技术网 > IT编程>开发语言>.net > .net 多线程 Thread ThreadPool Task

.net 多线程 Thread ThreadPool Task

2019年02月25日  | 移动技术网IT编程  | 我要评论

太空豆,瑞士幸运28swisslotterys,47岁李嘉欣近照皮肤紧致

先准备一个耗时方法
/// <summary>
/// 耗时方法
/// </summary>
/// <param name="name"></param>
private void dosomething(string name)
{
                 console.writeline($"开始执行{name}, {thread.currentthread.managedthreadid.tostring("00")} ,{datetime.now}");
                 int num = 1;

                 for (int i = 0; i < 100000000; i++)
                 {
                                 num++;
                 }
                 thread.sleep(1000);

              console.writeline($"结束执行{name}, {thread.currentthread.managedthreadid.tostring("00")} ,{datetime.now},{num}");
}
 
 
.net framework框架1.0和1.1时期,多线程,用thread
 
threadstart  threadstart = new threadstart(()=>this.dosomething("thread"));
thread thread = new thread(threadstart);
thread.start();// 开始执行多线程任务了。
 
//thread.start();默认是前台线程,ui退出后,还是会继续执行完,如果thread.isbackgroud=true;//就变成主线程关闭就直接关闭了
 
thread.join();//这个方法是让主线程等着当前线程完成之后再执行
 
thread.suspend();//暂停  过时方法不推荐
thread.resume();//重启  过时方法不推荐
thread.abort();//销毁  过时方法不推荐
 
基于thread封装一个支持回调
private void threadwithcallback(threadstart threadstart  action callback)
{
          threadstart  startnew = new threadstart(
                  ()=>
                     {
                             threadstart.invoke();//执行传入的线程方法
                             callback.invoke(); //执行回调函数
                     } 
             );
          thread thread = new thread(startnew);
           thread.start();
}
 
调用这个方法:
threadstart threadstart = new threadstart(() => this.dosomething("thread"));
 action callback = () => console.writeline("这是回调函数");
 
this.threadwithcallback(threadstart , callback );
 
 
/// <summary>
/// 基于thread封装带返回的
/// </summary>
/// <typeparam name="t"></typeparam>
/// <param name="funct"></param>
/// <returns></returns>
private func<t> threadwithreturn<t>(func<t> funct)
{
           t t = default(t);

            threadstart startnew = new threadstart(()=> {
            t = funct.invoke();
            });
            thread thread = new thread(startnew);
            thread.start();
            return new func<t>(()=> 
            {
                thread.join();
                return t;
             });
}
 
调用这个方法
{
func<int> func = this.threadwithreturn(() => 222);

console.writeline( func.invoke());

}
 
.net framework框架2.0时期,多线程,用threadpool
 
threadpool.queueuserworkitem(o=>
{
          thread.sleep(2000);
           this.dosomething("threadpool");
} //这个就是开启一个子线程。
 
如果要控制等待,就用
 manualresetevent mre = new manualresetevent(false);//默认填false
threadpool.queueuserworkitem(o => {
            thread.sleep(2000);
            this.dosomething("threadpool");
            mre.set();//这个设置之后
});
            mre.waitone();//当mre.set之后,主线程就可以等待子线程执行完成之后再执行
             
            console.writeline($"this is end ");
 
.net framework框架3.0时期,多线程,用task
 
task.run(()=>this.dosomething("task")); //就开启执行子线程了
 
推荐使用task的原因:1.使用的是线程池的线程,全部都是后台线程
                                    2、api很强大
 
taskfactory taskfactory = task.factory();
taskfactory.startnew(()=>this.dosomething("task1"));//跟task.run的效果一样
taskfactory.startnew(()=>this.dosomething("task2"));
taskfactory.startnew(()=>this.dosomething("task3"));
taskfactory.startnew(()=>this.dosomething("task4"));
taskfactory.startnew(()=>this.dosomething("task5"));//执行多个子线程
 
需要多线程加快速度,同时又要求全部完成后,执行新的任务
多业务操作希望并发,但是全部完成后,执行新的任务
 
list<task> tklist = new list<task>();
 
tklist.add(taskfactory.startnew(()=>this.dosomething("task1")));
tklist.add(taskfactory.startnew(()=>this.dosomething("task2")));
tklist.add(taskfactory.startnew(()=>this.dosomething("task3")));
 
task.waitall(tklist.toarray());
console.writeline("全部完成之后,执行任务");
 
 
需要多线程加快速度,同时又要求一个任务完成后,执行新的任务
多业务操作希望并发,但是一个任务完成后,执行新的任务
task.waitany(tklist.toarray());
console.writeline("一个任务完成之后,执行任务");
 
不过两个方法同时使用的时候,waitany放在waitall前面。
 
但是上面2个方法都会卡住ui界面
 
还有2个方法也可以执行同样的任务,而且不卡界面,类似回调
 
taskfactory.continuewhenall(tasks.toarray(), tlist => { console.writeline("全部执行完之后执行,而且不卡界面"); });
 
taskfactory.continuewhenany(tasks.toarray(), t => { console.writeline("执行一个任务后,执行,不卡界面"); });
 
4种方法可以一起使用,如果想先执行不卡界面的方法,后执行task.waitall的方法,就可以先把这2个方法也添加进集合里面
tasks.add(taskfactory.continuewhenall(tasks.toarray(), tlist => { console.writeline("全部执行完之后执行,而且不卡界面"); }));

tasks.add(taskfactory.continuewhenany(tasks.toarray(), t => { console.writeline("执行一个任务后,执行,不卡界面"); }));
 
task.waitany(tklist.toarray());
console.writeline("一个任务完成之后,执行任务");
task.waitall(tklist.toarray());
console.writeline("全部完成之后,执行任务");
 
 
可以给每个子线程,取一个标识

task tack= taskfactory.startnew(t => console.writeline("新的一个任务"),"标识token"); //设置标识
console.writeline(tack.asyncstate.tostring());//获取标识并且打印 tack.asyncstate
 
获取返回值
//task<int> task = taskfactory.startnew(()=>123456);
//int result = task.result;
//console.writeline(result);
 
 
一个线程执行后马上执行另一个
taskfactory.startnew(t=>this.dosomething("第一个方法")).continuwith(t=>console.writeline("第二个"))
 
 
 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网