How to store methods in a method that take methods as a parameters with action but using Task(Async)

huangapple go评论69阅读模式
英文:

How to store methods in a method that take methods as a parameters with action but using Task(Async)

问题

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 allTasks = new List();

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");
}

async Task TaskDoneAction(Action[] tasks)
{
    foreach (Action task in tasks)
    {
        Task t = Task.Run(task);
        allTasks.Add(t);
    }

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

}

英文:
    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");
        }
    }

How to store methods in a method that take methods as a parameters with action but using Task(Async)

This is my output, although I don't understand why the output start with task 1 then 3 then 2. Since I add them with tasks a,b, and c, following the order of Task1 Task2, Task3 and code should run line by line. But that's just an additional question.

My main question is currently I can add the task into the "TaskDone" method, but all those tasks I need to declare first at the start and I want to skip this part. What I want to achieve is to create is to able to throw any task or method directly to a method that takes action as a parameter. The method doesn't know the number of tasks is thrown in but still able to handle it all.

Sorry if I am a bit unclear as I am a beginner and didn't find the answer I want on the internet

 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");
    }

答案1

得分: 1

  1. 开始任务的顺序(那些打算在同一时间开始的任务)实际上是随机的(取决于许多因素以及线程池和任务调度程序的当前状态,因此可以被视为随机的),您不应依赖于它。

  2. 该方法可以具有 Func<Task> 类型的参数。但是,您仍然需要在某个地方启动任务,但可以在方法本身中完成,如下所示:

    async Task RunAll(params Func&lt;Task&gt;[] methods)
    {
    	var tasks = methods.Select(m=&gt;Task.Run(m)).ToList();
    	await Task.WhenAll(tasks);
    }
    
    async Task Main()
    {
    	await RunAll(Looping1, Looping2, Looping3);
    }
英文:
  1. the order of starting tasks (that are meant to be started on the same time) are practically random (depends on so many thing and current state of the thread pool and task scheduler so it can be considered random), and you should not rely on it.

  2. The method can have parameters of type Func<Task>. However you have to still start the task somewhere, but it can be done in the method itself, like:

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

huangapple
  • 本文由 发表于 2023年2月6日 13:58:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/75357798.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定