C#利用Task实现多任务一起执行的方法

498 阅读1分钟

1、 Task的实例运用一

private static void Main(string[] args)
{
    List<Task> tasks = new List<Task>
    {
        Task.Run(() => Debug.WriteLine("张三开发前端")),
        Task.Run(() => Debug.WriteLine("李四开发API")),
        Task.Run(() => Debug.WriteLine("王五开发后台")),
        Task.Run(() => Debug.WriteLine("赵六模块整理")),
    };
    //阻塞到任意一任务完成(不卡界面特性丢失,因为主线程在等待)
    Task.WaitAny(tasks.ToArray());
    Debug.WriteLine("任意一任务完成");
    //阻塞到等待所有的任务完成(不卡界面特性丢失,因为主线程在等待)
    Task.WaitAll(tasks.ToArray());
    Debug.WriteLine("全部任务完成");
    //不阻塞主线程,指定任务完成后,执行某些操作
    tasks[0].ContinueWith(t => Debug.WriteLine("张三的任务完成后输出日志"));
    //不阻塞主线程,任意一任务完成后,执行某些操作
    Task.Factory.ContinueWhenAny(tasks.ToArray(), t => Debug.WriteLine("任意一任务完成输出日       志"));
    //不阻塞主线程,全部任务完成后,执行某些操作
    Task.Factory.ContinueWhenAll(tasks.ToArray(), t => Debug.WriteLine("全部任务完成输出日志"));
}

2、Task的实例运用二(限定线程数完成任务)

private static void Main(string[] args)
{
    #region 组装数据(模拟300个任务)
    var dataArr = new int[300][]; //数据数组
    for (int i = 0; i < 300; i++)
    {
        var temp = new int[i];
        for (int j = 0; j < i; j++)
        {
            temp[j] = j;
        }
        dataArr[i] = temp;
    }
    #endregion
 
    #region 限定线程数完成任务
    var threadNum = 24; //定义完成任务的线程数量(一般定义CPU核数 * 3)
    var taskList = new List<Task>(); //任务集合
    for (int i = 0; i < dataArr.Length; i++)
    {
        var currEnt = dataArr[i]; //当前数据任务
        taskList.Add(Task.Run(() =>
        {
            Debug.WriteLine($"CurrThreadId={Thread.CurrentThread.ManagedThreadId},数据编号:{string.Join(",", currEnt)}");
            Thread.Sleep(new Random().Next(currEnt.Length)); //模拟执行任务耗时
            Debug.WriteLine($"CurrThreadId={Thread.CurrentThread.ManagedThreadId},任务执行完成!");
        }));
        if(taskList.Count == threadNum)
        {
            Task.WaitAny(taskList.ToArray()); //等待任务集合中任一任务完成
            taskList = taskList.Where(m => m.Status == TaskStatus.Running).ToList(); //筛选正在运行但未完成任务
        }
    }
    Task.WaitAll(taskList.ToArray()); //等待所有任务执行完成
    Debug.WriteLine($"所有任务已完成!");
    #endregion
    Console.ReadKey();
}