using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace TaskTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine($"Task 主线程startID:{Thread.CurrentThread.ManagedThreadId}");
//Task启动方式一
//Task task = new Task(() =>
//{
// Thread.Sleep(2000);
// Console.WriteLine($"Task 子线线程1ID:{Thread.CurrentThread.ManagedThreadId}");
//});
//task.Start();
//Task 启动方式二
//Task.Run(() =>
//{
// Thread.Sleep(2000);
// Console.WriteLine($"Task 子线程1ID:{Thread.CurrentThread.ManagedThreadId}");
//});
List<Task> lst = new List<Task>();
lst.Add(Task.Run(() => { Thread.Sleep(2000); Console.WriteLine($"Task 子线程2ID:{Thread.CurrentThread.ManagedThreadId}"); }));
lst.Add(Task.Run(() => { Thread.Sleep(3000); Console.WriteLine($"Task 子线程3ID:{Thread.CurrentThread.ManagedThreadId}"); }));
//TaskFactory tf = new TaskFactory();
//tf.ContinueWhenAny(lst.ToArray(), t => { Console.WriteLine("获取红包"); });//阻塞子线程,直到 lst对象中 任一一个子线程返回,则执行委托函数代码,主线程不会被阻塞,不卡界面;
//tf.ContinueWhenAll(lst.ToArray(), t => { Console.WriteLine("庆功宴"); });////阻塞子线程,直到 lst对象中 全部子线程返回,则执行委托函数代码,主线程不会被阻塞,不卡界面;
//lst[0].ContinueWith(t => { Console.WriteLine("异步多线程2回调函数执行"); });//ContinueWith表示某个线程执行回调函数,这里表示lst第一个子线程完成后执行的回调函数;
Task.WaitAny(lst.ToArray());//阻塞所有线程,直到 lst对象中 任一一个子线程返回,则执行后续代码,所以主线程也会被阻塞,卡界面;
Console.WriteLine("Task 异步多线程有某个子线程已经返回");
Task.WaitAll(lst.ToArray());//阻塞所有线程,直到 lst对象中 全部子线程返回结束,则执行后续代码,所以主线程也会被阻塞,卡界面
Console.WriteLine($"Task 主线程endID:{Thread.CurrentThread.ManagedThreadId}");
Console.ReadKey();
}
}
}
1.Task通过方式一和方式二启动结果和Thread效果一样,先主线程跑完,后启动子线程去完成
2.Task执行顺序控制--Task.WaitAny(),Task.WaitAll(),需要传入两个Task类型的数组,这两个都会阻塞主线程
Task.WaitAny(lst.ToArray())//阻塞所有线程,直到 lst对象中任一一个子线程返回,则执行后续代码,所以主线程也会被阻塞,卡界面;
Task.WaitAll(lst.ToArray());//阻塞所有线程,直到 lst对象中全部子线程返回结束,则执行后续代码,所以主线程也会被阻塞,卡界面;
上述代码执行结果:
3.执行回调函数控制顺序--不卡主线程--TaskFactory类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace TaskTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine($"Task 主线程startID:
List<Task> lst = new List<Task>();
lst.Add(Task.Run(() => { Thread.Sleep(2000); Console.WriteLine($"Task 子线程2ID:{Thread.CurrentThread.ManagedThreadId}"); }));
lst.Add(Task.Run(() => { Thread.Sleep(3000); Console.WriteLine($"Task 子线程3ID:{Thread.CurrentThread.ManagedThreadId}"); }));
TaskFactory tf = new TaskFactory();
tf.ContinueWhenAny(lst.ToArray(), t => { Console.WriteLine("获取红包"); });//阻塞子线程,直到任一一个子线程返回,则执行委托函数代码,主线程不会被阻塞,不卡界面;
tf.ContinueWhenAll(lst.ToArray(), t => { Console.WriteLine("庆功宴"); });////阻塞子线程,直到全部子线程返回,则执行委托函数代码,主线程不会被阻塞,不卡界面;
//lst[0].ContinueWith(t => { Console.WriteLine("异步多线程2回调函数执行"); });//ContinueWith表示某个线程执行回调函数
Console.WriteLine($"Task 主线程endID:{Thread.CurrentThread.ManagedThreadId}");
Console.ReadKey();
}
}
}
结果:主线程先执行完成,子线程2返回后立即执行"获取红包”,子线程2和3全部完成后执行“庆功宴”,
但是可以发现ContinueWhenAny(),ContinueWhenAll()都不会卡主线程,
也可以用ContinueWith()去写某个子线程执行结束的回调函数,同样不会卡主线程