一、C#多线程
关键字集
线程方法
- Task.WaitAll(task1, task2):等待两个任务都完成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| Task task1 = Task.Run(() => { for (int i = 0; i < 5; i++) { Console.WriteLine($"Task 1: Working {i + 1}/5"); Task.Delay(1000).Wait(); } Console.WriteLine("Task 1: Completed"); });
Task task2 = Task.Run(() => { for (int i = 0; i < 5; i++) { Console.WriteLine($"Task 2: Working {i + 1}/5"); Task.Delay(1500).Wait(); } Console.WriteLine("Task 2: Completed"); });
Task.WaitAll(task1, task2);
|
- Task.WhenAll(线程集合):线程集合全部执行完后
1 2 3 4
| private async void 方法() { await Task.Run(异步线程); }
|
并发线程:同样成对使用async和await
1 2 3 4 5 6 7 8
| List<Task<string>> Tanks = new();
Data.books.Foreach(book => Tasks.Add(Task.Run(book.Search)));
var tasks = await Task.WhenAll(Tasks);
|
- Task.ContinueWith():Task线程回调方法,防止先结束的线程等待(未用到await,故不需async)
- 问题:主线程不会等待,继续往下执行
- 解决:事件(event)
1 2 3 4 5
| foreach (var book in Date.Books) { Task.Run(book.Search).ContinueWith(t => AppendLine("输出")); }
|
所有逻辑结束之后执行事件
一、单线程
单线程阻塞窗口运行
1 2 3 4 5 6 7
| private void button1_Click(object sender, EventArgs e) { Thread.Sleep(3000); MessageBox.Show("素菜做好了","友情提示"); Thread.Sleep(5000); MessageBox.Show("荤菜做好了", "友情提示"); }
|
二、Thread线程
新开一个线程用来执行方法委托,也可使用Lambda表达式
1 2 3 4 5 6 7 8 9 10 11 12 13
| private void button2_Click(object sender, EventArgs e) { Thread t = new Thread(() => { Thread.Sleep(3000); MessageBox.Show("素菜做好了", "友情提示"); Thread.Sleep(5000); MessageBox.Show("荤菜做好了", "友情提示"); }); t.Start(); }
|
三、Task任务(C#更推荐)
Task底层使用的也是Thread线程,Run一个方法委托或者Lambda表达式
Task:提供了很多线程相关的管理如线程池,性能会更好,管理更方便
1 2 3 4 5 6 7 8 9 10 11
| private void button3_Click(object sender, EventArgs e) { Task.Run(() => { Thread.Sleep(3000); MessageBox.Show("素菜做好了", "友情提示"); Thread.Sleep(5000); MessageBox.Show("荤菜做好了", "友情提示"); }); }
|
四、两个Task同时执行
将每一种菜放入不同线程,同时执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| private void button4_Click(object sender, EventArgs e) { Task.Run(() => { Thread.Sleep(3000); MessageBox.Show("素菜做好了", "友情提示"); }); Task.Run(() => { Thread.Sleep(5000); MessageBox.Show("荤菜做好了", "友情提示"); }); }
|
五、异步线程
!!不使用异步线程则会先执行MessageBox.Show(“饭做好了,快来吃吧”);!!
加入async和await关键字使线程变成异步线程
异步线程:Task执行完才执行Run外的程序(等某个线程完成以后才去做另外一件事情)
1 2 3 4 5 6 7 8 9 10 11 12 13
| private async void button5_Click(object sender, EventArgs e) { await Task.Run(() => { Thread.Sleep(3000); MessageBox.Show("素菜做好了", "友情提示"); Thread.Sleep(5000); MessageBox.Show("荤菜做好了", "友情提示"); });
MessageBox.Show("饭做好了,快来吃吧"); }
|
问题:如果是多个Task同时执行,则线程之间就不是并行的了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| private async void button5_Click(object sender, EventArgs e) { await Task.Run(() => { Thread.Sleep(3000); MessageBox.Show("素菜做好了", "友情提示"); }); await Task.Run(() => { Thread.Sleep(5000); MessageBox.Show("荤菜做好了", "友情提示"); });
MessageBox.Show("饭做好了,快来吃吧"); }
|