C# Task任務佇列
阿新 • • 發佈:2021-05-30
新建一個Winfrom專案,加入下面程式碼:
using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace 執行緒2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { Task task1 = new Task(() => { Thread.Sleep(400); Console.WriteLine("task1"); }); Task task2 = new Task(() => { Thread.Sleep(300); Console.WriteLine("task2"); }); Task task3 = new Task(() => { Thread.Sleep(200); Console.WriteLine("task3"); }); Task task4 = new Task(() => { Thread.Sleep(100); Console.WriteLine("task4"); }); task1.Start(); task2.Start(); task3.Start(); task4.Start(); } } }
執行:
由於延時不同,最先執行的Task1,反而最後一個執行完,那麼如果要求從任務1,一直執行到任務4,怎麼寫呢?
程式碼:
using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace 執行緒2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private List<Task> TaskList = new List<Task>(); private void Form1_Load(object sender, EventArgs e) { Task task1 = new Task(() => { Thread.Sleep(400); Console.WriteLine("task1"); }); Task task2 = new Task(() => { Thread.Sleep(300); Console.WriteLine("task2"); }); Task task3 = new Task(() => { Thread.Sleep(200); Console.WriteLine("task3"); }); Task task4 = new Task(() => { Thread.Sleep(100); Console.WriteLine("task4"); }); TaskList.Add(task1); TaskList.Add(task2); TaskList.Add(task3); TaskList.Add(task4); foreach (Task task in TaskList) { task.Start(); task.Wait(); } } } }
執行:
用上面的方法雖然有效,但會阻塞主執行緒,導致winfrom介面卡住,無法操作,那麼用異常的方法怎麼樣呢?
程式碼:
using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace 執行緒2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private List<Task> TaskList = new List<Task>(); private void Form1_Load(object sender, EventArgs e) { } private void Button_Calculate_Click(object sender, EventArgs e) { Task task1 = new Task(async () => { await Task.Delay(TimeSpan.FromSeconds(4)); Console.WriteLine("task1"); }); Task task2 = new Task(async () => { await Task.Delay(TimeSpan.FromSeconds(3)); Console.WriteLine("task2"); }); Task task3 = new Task(async () => { await Task.Delay(TimeSpan.FromSeconds(2)); Console.WriteLine("task3"); }); Task task4 = new Task(async () => { await Task.Delay(TimeSpan.FromSeconds(1)); Console.WriteLine("task4"); }); TaskList.Add(task1); TaskList.Add(task2); TaskList.Add(task3); TaskList.Add(task4); foreach (Task task in TaskList) { task.Start(); task.Wait(); } } } }
執行:
用非同步方式雖然介面不會卡住,但另一個問題來了,task.wait()方法似乎沒有效果。裡面的任務佇列依然沒有按順序來執行。
後面我終於找到方法了,用下面的方法既不會卡住UI,也會按照佇列來執行,雖然寫法不是特別好,讀者可以按下面方法自己封裝了。
private void Test()
{
Task.Run(() =>
{
Task t1 = new Task(() => {
Thread.Sleep(2000);
Console.WriteLine("t1");
num = 1;
});
t1.Start();
t1.Wait();
Task t2 = new Task(() => {
Thread.Sleep(1000);
Console.WriteLine("t2");
num = 3;
});
t2.Start();
t2.Wait();
Console.WriteLine("執行緒執行完畢");
});
}
執行:
如果你這個帖子對你有用,歡迎給我點贊 + 留言,謝謝
end