进程是一种正在执行的程序。前端
线程是程序中的一个执行流。数据库
多线程是指一个程序中能够同时运行多个不一样的线程来执行不一样的任务。编程
Thread是建立和控制线程的类。后端
ManagedThreadId是线程ID。多线程
CurrentThread是获取当前正在运行的线程。异步
同步是调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为。(单线程)async
异步调用一旦开始,方法调用就会当即返回,调用者就能够继续后续的操做。(多线程)ide
主要有Thread,ThreadPool,Task异步编程
Thread就是线程,须要本身调度,直接跟系统对接,相对管理比较复杂及效率差。函数
ThreadPool是Thread的一个升级版,ThreadPool是从线程池中获取线程,若是线程池中又空闲的元素,则直接调用,若是没有才会建立,而Thread则是会一直建立新的线程,要知道开启一个线程就算什么事都不作也会消耗大约1m的内存,是很是浪费性能的。可是ThreadPool提供的接口比较少。
Task和ThreadPool是同样的,都是从线程池中取空闲的线程。比ThreadPool调用接口更加丰富。目前.Net使用多线程管理,应该优先使用Task。
代码:
/// <summary> /// 多线程发展历史 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnHistory_Click(object sender, EventArgs e) { Console.WriteLine($"Thread start id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); var threadStart = new ThreadStart(DoNothing); var thread = new Thread(threadStart); thread.Start(); Console.WriteLine($"Thread end id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); Thread.Sleep(3000); Console.WriteLine($"ThreadPool start id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); var callback = new WaitCallback(DoNothing); ThreadPool.QueueUserWorkItem(callback); Console.WriteLine($"ThreadPool end id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); Thread.Sleep(3000); Console.WriteLine($"Task start id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); Action action = DoNothing; Task task = new Task(action); task.Start(); Console.WriteLine($"Task end id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); }
特色:
代码:
/// <summary> /// 同步(单线程) /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSync_Click(object sender, EventArgs e) { Console.WriteLine($"btnSync_Click start id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); for (int i = 0; i < 5; i++) { DoNothing(); } Console.WriteLine($"btnSync_Click end id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); } /// <summary> /// 异步(多线程) /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnAsync_Click(object sender, EventArgs e) { Console.WriteLine($"btnAsync_Click start id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); for (int i = 0; i < 5; i++) { var ts = new ThreadStart(DoNothing); var t = new Thread(ts); t.Start(); } Console.WriteLine($"btnAsync_Click end id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); } private void DoNothing() { Console.WriteLine($"DoNothing start id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); Thread.Sleep(2000); Console.WriteLine($"DoNothing end id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); }
一、经过调用任务类构造函数实例化,但经过调用其Start()启动任务。
Task t1 = new Task(action, "alpha"); t1.Start();
二、经过调用TaskFactory.StartNew(Action < Object>,Object)方法在单个方法调用中实例化和启动任务。
Task t2 = Task.Factory.StartNew(action, "beta");
三、经过调用Run(Action)方法在单个方法调用中实例化和启动任务。
Task t3 = Task.Run(action);
Result 属性将阻止调用线程,直到任务完成。
Task<int> task1 = Task<int>.Factory.StartNew(() => 1); int i = task1.Result;
能够经过调用 Wait 方法来等待一个或多个任务完成,从而同步调用线程的执行以及它启动的异步任务。
调用无参数 Wait() 方法以无条件等待,直到任务完成。
调用Wait(Int32)和 Wait(TimeSpan) 方法会阻止调用线程,直到任务完成或超时间隔(以先达到者为准)为止。
调用WaitAny(Task[])方法等待一组任务中第一个任务完成。
调用WaitAll(Task[])方法来等待一系列任务所有完成。
调用代码能够经过使用 try/catch 块中的如下任意方法来处理异常:
代码:
var task1 = Task.Run(() => { throw new Exception("This exception is expected!"); }); try { task1.Wait(); } catch (Exception e) { Console.WriteLine(e.Message); } Console.ReadKey();
你可使用 CancellationTokenSource 类在之后某一时间发出取消请求。
static void Main(string[] args) { var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token; var tasks = new ConcurrentBag<Task>(); Task tc; for (int i = 0; i < 10; i++) { var k = i; tc = Task.Run(() => DoNothing(k, token), token); tasks.Add(tc); } char ch = Console.ReadKey().KeyChar; if (ch == 'c' || ch == 'C') { tokenSource.Cancel(); Console.WriteLine("\n开始取消任务."); } try { Task.WhenAll(tasks.ToArray()); } catch (OperationCanceledException) { Console.WriteLine($"\n{nameof(OperationCanceledException)} thrown\n"); } finally { tokenSource.Dispose(); } Console.ReadKey(); } private static void DoNothing(int i, CancellationToken ct) { Console.WriteLine($"DoNothing start index:{i} id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); Thread.Sleep(i * 1000); if (ct.IsCancellationRequested) { Console.WriteLine($"任务已取消 index:{i} id:{Thread.CurrentThread.ManagedThreadId} "); ct.ThrowIfCancellationRequested(); } Console.WriteLine($"DoNothing end index:{i} id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); }
代码:
/// <summary> /// Task实际案例 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnTask_Click(object sender, EventArgs e) { Console.WriteLine($"项目组接到任务 id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); Console.WriteLine($"项目经理设计数据库,设计原型,分配任务 id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); List<Task> tasks = new List<Task>(); tasks.Add(Task.Run(() => Coding("赵XX","前端页面"))); tasks.Add(Task.Run(() => Coding("王XX", "IOS页面"))); tasks.Add(Task.Run(() => Coding("黄XX", "后端接口"))); tasks.Add(Task.Run(() => Coding("杜XX", "后端接口"))); TaskFactory taskFactory = new TaskFactory(); taskFactory.ContinueWhenAll(tasks.ToArray(), t => { Console.WriteLine($"项目经理发布,测试人员测试任务 id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); }); } private void Coding(string personName,string taskName) { Console.WriteLine($"{personName}开发{taskName} id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); Thread.Sleep(2000); }
Async 和 Await几乎与建立同步方法同样建立异步方法。
代码:
/// <summary> /// Async和Await应用 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnAsyncAndAwait_Click(object sender, EventArgs e) { Console.WriteLine($"btnAsyncAndAwait_Click start id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); DoNothingAsync(); Console.WriteLine($"btnAsyncAndAwait_Click end id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); } private async Task DoNothingAsync() { Console.WriteLine($"DoNothingAsync start id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); await Task.Run(() => { Console.WriteLine($"DoNothingAsync Task start id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); Thread.Sleep(2000); Console.WriteLine($"DoNothingAsync Task end id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); }); Console.WriteLine($"DoNothingAsync end id:{Thread.CurrentThread.ManagedThreadId} time:{DateTime.Now}"); }