Task是.NET Framework3.0出现的,线程是基于线程池的,然后提供丰富的api,Thread方法很多很强大,但是太过强大,没有限制。
DoSomethingLong方法如下:
/// <summary> /// 一个比较耗时耗资源的私有方法 /// </summary> /// <param name="name"></param> private void DoSomethingLong(string name) { Console.WriteLine($"****************DoSomethingLong Start {name} {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************"); long lResult = 0; for (int i = 0; i < 1_000_000_000; i++) { lResult += i; } Thread.Sleep(2000); Console.WriteLine($"****************DoSomethingLong End {name} {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} {lResult}***************"); }
Task的使用:
{ Task task = new Task(() => this.DoSomethingLong("btnTask_Click_1")); task.Start(); } { Task task = Task.Run(() => this.DoSomethingLong("btnTask_Click_2")); } { TaskFactory taskFactory = Task.Factory; Task task = taskFactory.StartNew(() => this.DoSomethingLong("btnTask_Click_3")); }
如果这样去调用:
ThreadPool.SetMaxThreads(8, 8); for (int i = 0; i < 100; i++) { int k = i; Task.Run(() => { Console.WriteLine($"This is {k} running ThreadId={Thread.CurrentThread.ManagedThreadId.ToString("00")}"); Thread.Sleep(2000); }); }
如果去掉设置最大线程的代码:
for (int i = 0; i < 100; i++) { int k = i; Task.Run(() => { Console.WriteLine($"This is {k} running ThreadId={Thread.CurrentThread.ManagedThreadId.ToString("00")}"); Thread.Sleep(2000); }); }
运行结果如下:
ThreadPool.SetMaxThreads(8, 8);
线程池是单例的,全局唯一的,设置后,同时并发的Task只有8个,而且是复用的,Task的线程是源于线程池的,全局的,请不要这样设置。
假如我想控制下Task的并发数量,改怎么做?
{ Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Console.WriteLine("在Sleep之前"); Thread.Sleep(2000);//同步等待--当前线程等待2s 然后继续 Console.WriteLine("在Sleep之后"); stopwatch.Stop(); Console.WriteLine($"Sleep耗时{stopwatch.ElapsedMilliseconds}"); } { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Console.WriteLine("在Delay之前"); Task task = Task.Delay(2000) .ContinueWith(t => { stopwatch.Stop(); Console.WriteLine($"Delay耗时{stopwatch.ElapsedMilliseconds}"); Console.WriteLine($"This is ThreadId={Thread.CurrentThread.ManagedThreadId.ToString("00")}"); });//异步等待--等待2s后启动新任务 Console.WriteLine("在Delay之后"); stopwatch.Stop(); Console.WriteLine($"Delay耗时{stopwatch.ElapsedMilliseconds}"); }
运行结果如下:
如果将最后一个stopwatch注释掉:
{ Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Console.WriteLine("在Sleep之前"); Thread.Sleep(2000);//同步等待--当前线程等待2s 然后继续 Console.WriteLine("在Sleep之后"); stopwatch.Stop(); Console.WriteLine($"Sleep耗时{stopwatch.ElapsedMilliseconds}"); } { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Co