.net 多線程 Thread ThreadPool Task

先準備一個耗時方法
/// <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("第二個"))
相關文章
相關標籤/搜索