在完成时处理异步任务

问题描述 投票:0回答:1

我正在尝试在每个异步任务完成时处理它们。这些任务有不同的结果集。我喜欢同时执行这些任务,但需要在任何任务完成时处理结果。

当异步函数具有相同的返回类型时,有很多 google 搜索结果,但是,我无法找到具有不同结果集的结果集。

private async Task CompleteTasksAsync()
{
        var taskA = GetStringAsync();
        var taskB = GetIntAsync();
        var taskC = GetStringListAsync();
        var taskD = GetGenericAsync<double>(1d);

        //var tasks = new[] {taskA, taskB, taskC, taskD} // this will only work if all tasks have same return type

        await Task.WhenAll(taskA, taskB, taskC, taskD); //This statement will wait until all tasks are completed

        // when Task A finished Console.WriteLine(taskA.Result);
        // when Task B finished Console.WriteLine(taskB.Result);
        // when Task C finished Console.WriteLine(taskC.Result);
        // when Task D finished Console.WriteLine(taskD.Result);
}

private Task<string> GetStringAsync() => Task.FromResult("string");
private Task<int> GetIntAsync() => Task.FromResult(1);
private Task<List<string>> GetStringListAsync() => Task.FromResult(new List<string> { "string"});
private Task<T> GetGenericAsync<T>(T data) => Task.FromResult(data);
c# asynchronous .net-6.0 .net-7.0
1个回答
3
投票

可以使用

Task.WhenAny
方法等待第一个任务完成,然后处理它的结果,将其从剩余任务列表中移除,重复直到所有任务完成。

private async Task CompleteTasksAsync()
{
    var taskA = GetStringAsync();
    var taskB = GetIntAsync();
    var taskC = GetStringListAsync();
    var taskD = GetGenericAsync<double>(1d);

    var tasks = new List<Task> { taskA, taskB, taskC, taskD };

    while (tasks.Count > 0)
    {
        var completedTask = await Task.WhenAny(tasks);
        tasks.Remove(completedTask);

        if (completedTask == taskA)
        {
            // we can't write `await completedTask` so we need to use original tasks with type parameter 
            Console.WriteLine(await taskA);
        }
        else if (completedTask == taskB)
        {
            Console.WriteLine(await taskB);
        }
        else if (completedTask == taskC)
        {
            var result = await taskC;
            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
        }
        else if (completedTask == taskD)
        {
            Console.WriteLine(await taskD);
        }
    }
}

同样的事情还有另一种方法。您可以使用

Task
 方法为每个 
Task.ContinueWith
添加完成操作,然后等待所有任务完成。

Task.ContinueWith
创建一个在目标
Task
完成时异步执行的延续。

private async Task CompleteTasksAsync()
{
    var taskA = GetStringAsync().ContinueWith(t => Console.WriteLine(t.Result));
    var taskB = GetIntAsync().ContinueWith(t => Console.WriteLine(t.Result));
    var taskC = GetStringListAsync().ContinueWith(t => Console.WriteLine(string.Join(",", t.Result)));
    var taskD = GetGenericAsync<double>(1d).ContinueWith(t => Console.WriteLine(t.Result));

    // Wait for all tasks to complete
    await Task.WhenAll(taskA, taskB, taskC, taskD);
}
© www.soinside.com 2019 - 2024. All rights reserved.