.net 多线程 Thread ThreadPool Task
程序员文章站
2022-04-20 21:10:37
先准备一个耗时方法 /// /// 耗时方法/// /// private void DoSomeThing(string name){ Console.WriteLine($"开始执行{name}, {Th ......
先准备一个耗时方法
/// <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}");
}
/// 耗时方法
/// </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("这是回调函数");
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;
});
}
/// 基于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());
}
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 ");
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("全部执行完之后执行,而且不卡界面"); });
4种方法可以一起使用,如果想先执行不卡界面的方法,后执行task.waitall的方法,就可以先把这2个方法也添加进集合里面
tasks.add(taskfactory.continuewhenall(tasks.toarray(), tlist => { console.writeline("全部执行完之后执行,而且不卡界面"); }));
tasks.add(taskfactory.continuewhenany(tasks.toarray(), t => { 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);
//int result = task.result;
//console.writeline(result);
一个线程执行后马上执行另一个
taskfactory.startnew(t=>this.dosomething("第一个方法")).continuwith(t=>console.writeline("第二个"))
下一篇: 经常吃糙米好吗?糙米有哪些功效与作用
推荐阅读
-
.NET进阶篇06-async异步、thread多线程4
-
.NET进阶篇06-async异步、thread多线程2
-
Asp.Net Core 轻松学-多线程之Task快速上手
-
Asp.Net Core 轻松学-多线程之Task(补充)
-
.net 多线程 Thread ThreadPool Task
-
.NET多线程之Thread、Task、ThreadPool、Timer
-
.NET进阶篇06-async异步、thread多线程3
-
.NET进阶篇06-async异步、thread多线程4
-
那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)
-
.NET进阶篇06-async异步、thread多线程2