将 WhenAll 与动态大小列表一起使用

Using WhenAny With Dynamic Sized List

有谁知道如果在等待后将元素添加到 listTask.WhenAny(IEnumerable<Task>) 是否会按预期工作?即:

class lunch {

    private List<Task> lunchTasks = new List<Task>();

    public void MakeLunch() {
        Task makeSandwich = new Task();
        Task eatSandwich = new Task();
        makeSandwich.Delay(-1);
        eatSandwich.Delay(-1);
        lunchTasks.Add(makeSandwich);
        lunchTasks.Add(eatSandwich);
        await Task.WhenAny(lunchTasks).ConfigureAwait(false);
    }

    public void CleanUp() {
        Task cleanUp = Task.CompletedTask;
        lunchTasks.Add(cleanUp);
    }
}

假设 CleanUp()MakeLunch() 之后异步调用,MakeLunch() 会 return/complete 吗?

没有。 WhenAny and WhenAll methods are making immediately a defensive copy of the supplied enumerable, as you can see in the source code:

public static Task<Task> WhenAny(IEnumerable<Task> tasks)
{
    if (tasks == null) throw new ArgumentNullException("tasks");
    Contract.EndContractBlock();

    // Make a defensive copy, as the user may manipulate the tasks collection
    // after we return but before the WhenAny asynchronously completes.
    List<Task> taskList = new List<Task>();
    foreach (Task task in tasks)
    {
        if (task == null) throw new ArgumentException(Environment
            .GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks");
        taskList.Add(task);
    }

    if (taskList.Count == 0)
    {
        throw new ArgumentException(Environment
            .GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), "tasks");
    }

    // Previously implemented CommonCWAnyLogic() can handle the rest
    return TaskFactory.CommonCWAnyLogic(taskList);
}

所以以后对可枚举的任何修改都将被忽略。