先準備一個耗時方法 /// <summary>/// 耗時方法/// </summary>/// <param name="name"></param>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}");
} .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("第二個"))