先准备一个耗时方法
/// <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.使用的是线程池的线程,所有都是后台线程
二、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("第二个"))