unity3d 如何将方法存储在将方法作为参数的方法中,该方法具有action但使用Task(异步)

tv6aics1  于 2023-02-09  发布在  其他
关注(0)|答案(1)|浏览(99)
using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using UnityEngine;
    
    public class Task22 : MonoBehaviour
    {
        public event Action callback;
        private Task allDone;
        List<Task> allTasks = new List<Task>();

        async void Start()
        {
            Task a = Task.Run(Looping1);
            Task b = Task.Run(Looping2);
            Task c = Task.Run(Looping3);
            TaskDone(a,b,c);
        }
    
        async Task TaskDone(params Task\[\] tasks)
        {
            foreach (Task task in tasks)
            {
                allTasks.Add(task);
            }

            Task allTaskDone = Task.WhenAll(allTasks);
            await allTaskDone;

            Debug.Log("AllTaskDone");
        }

        async Task Looping1()
        {
            Debug.Log("StartTask1");
            await Task.Delay(1000);
            Debug.Log("Task1Done");
        }

        async Task Looping2()
        {
            Debug.Log("StartTask2");
            await Task.Delay(2000);
            Debug.Log("Task2Done");
        }

        async Task Looping3()
        {
            Debug.Log("StartTask3");
            await Task.Delay(3000);
            Debug.Log("Task3Done");
        }
    }

这是我的输出,虽然我不明白为什么输出从任务1开始,然后是任务3,然后是任务2。因为我将它们与任务a、B和c一起添加,所以按照任务1、任务2、任务3和代码的顺序,它们应该逐行运行。但这只是一个附加问题。
我的主要问题是,目前我可以将任务添加到“TaskDone”方法中,但所有这些任务都需要在开始时首先声明,我希望跳过这一部分。我希望实现的是创建能够将任何任务或方法直接抛出到一个将操作作为参数的方法中。该方法不知道抛出的任务数量,但仍然能够处理所有任务。
对不起,如果我有点不清楚,因为我是一个初学者,并没有找到我想要的答案在互联网上

async Task TaskDoneAction(Action tasks//To store the task or throw method directly to here)
    {
        // Then I just do a for loop to see how many method or task is thrown here and add them to the list and do a callback when all tasks is done

        Task allTaskDone = Task.WhenAll(allTasks);
        await allTaskDone;
        Debug.Log("AllTaskDone");
    }
pes8fvy9

pes8fvy91#

1.任务的启动顺序(应该在同一时间启动)实际上是随机的(取决于线程池和任务调度器的当前状态和许多因素,因此可以认为它是随机的),您不应该依赖它。
1.这个方法可以有Func类型的参数。但是你仍然需要在某个地方启动这个任务,但是它可以在方法本身中完成,比如:

async Task RunAll(params Func<Task>[] methods)
    {
        var tasks = methods.Select(m=>Task.Run(m)).ToList();
        await Task.WhenAll(tasks);
    }
    
    async Task Main()
    {
        await RunAll(Looping1, Looping2, Looping3);
    }

相关问题