private void button7_Click(object sender, EventArgs e)
{
Console.WriteLine("111111");
Console.WriteLine("222222");
Console.WriteLine("333333");
Console.WriteLine("444444");
Console.WriteLine("555555");
Console.WriteLine("666666");
Console.WriteLine("777777");
Console.WriteLine("888888");
Console.WriteLine("999999");

//Task.Run(() => this.Coding("ouou", "ouou2"));
//Task.Run(() => this.Coding("ouou3", "ouou4"));
//Task.Run(() => this.Coding("ouou5", "ouou6"));
//Task.Run(() => this.Coding("ouou7", "ouou8"));
//Task.Run(() => this.Coding("ouou9", "ouou10"));
//Task.Run(() => this.Coding("ouou11", "ouou12"));


//等待所有线程完成
List<Task> taskList = new List<Task>();
taskList.Add(Task.Run(() => this.Coding("ouou", "ouou2")));
taskList.Add(Task.Run(() => this.Coding("ouou3", "ouou4")));
taskList.Add(Task.Run(() => this.Coding("ouou5", "ouou6")));
taskList.Add(Task.Run(() => this.Coding("ouou7", "ouou8")));
taskList.Add(Task.Run(() => this.Coding("ouou9", "ouou10")));
taskList.Add(Task.Run(() => this.Coding("ouou11", "ouou12")));

//Task.Run(() => //加上这行不卡界面,非推荐做法
1.尽量不要线程套线程
2.这里全部是子线程完成
//{
// Task.WaitAny(taskList.ToArray());
// Console.WriteLine("do half~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");

// //阻塞当前线程,直到全部任务结束,所以主线程阻塞了会卡界面
// Task.WaitAll(taskList.ToArray());

// Console.WriteLine("finish********************************");
//});

TaskFactory taskFactory = new TaskFactory();

taskFactory.ContinueWhenAny(taskList.ToArray(), tArray =>
{
Console.WriteLine($"half 66666666666");
});

//等待全部任务完成后,启动一个新的task来完成后续动作
taskFactory.ContinueWhenAll(taskList.ToArray(),tArray=>
{
Console.WriteLine($"finish xxxxxxxxxx");
});
//continue 的后续线程,可能是新线程,可能是刚完成的线程,还可能是同一个线程,不可能是主线程
//线程是不可预测的,几个动作先后都有可能
}

private void Coding(string name,string project)
{
Console.WriteLine("Coding start {0} {1} {2}", name, Thread.CurrentThread.ManagedThreadId.ToString("00"), DateTime.Now.ToString("HHmmss:fff"));

long lResult = 0;
for (int i = 0; i < 6000; i++)
{
lResult += i;
Thread.Sleep(1);
}

Console.WriteLine("Coding end {0} {1} {2} {3} ", name, Thread.CurrentThread.ManagedThreadId.ToString("00"), DateTime.Now.ToString("HHmmss:fff"), lResult);
}