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效果一样,先主线程跑完,后启动子线程去完成

gcd swift 异步线程 异步线程创建_gcd swift 异步线程

 

2.Task执行顺序控制--Task.WaitAny(),Task.WaitAll(),需要传入两个Task类型的数组,这两个都会阻塞主线程

 

Task.WaitAny(lst.ToArray())//阻塞所有线程,直到 lst对象中任一一个子线程返回,则执行后续代码,所以主线程也会被阻塞,卡界面;

Task.WaitAll(lst.ToArray());//阻塞所有线程,直到 lst对象中全部子线程返回结束,则执行后续代码,所以主线程也会被阻塞,卡界面;

上述代码执行结果:

gcd swift 异步线程 异步线程创建_gcd swift 异步线程_02

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()去写某个子线程执行结束的回调函数,同样不会卡主线程

gcd swift 异步线程 异步线程创建_主线程_03