You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Task.WhenAll()等待异步任务后赋值时如何避免重复检查条件

C#异步代码避免重复条件判断的优化方案

以下两种优化方案均无需重复编写两次条件判断,也不需要使用Task.Run,同时完全保留原代码并行执行异步任务的特性:


方案1:封装分支处理逻辑(适合分支较少的场景)

将每个条件分支的异步执行+赋值逻辑绑定封装,仅需要一次条件判断,无需声明额外的临时Task变量:

var tasks = new List<Task>();

if (myCondition)
{
    async Task AssignFoo() => result.foo = await getAsync();
    tasks.Add(AssignFoo());
}

if (myOtherCondition)
{
    async Task AssignBar() => result.bar = await getAsync2();
    tasks.Add(AssignBar());
}

await Task.WhenAll(tasks);

该方案和原代码执行逻辑完全等价,所有符合条件的异步任务会并行启动,全部执行完成后才会继续后续流程。


方案2:统一配置处理规则(适合分支较多、需要扩展的场景)

把条件判断、异步取值方法、赋值逻辑封装为配置统一管理,新增分支仅需要添加一条配置即可,全程无需重复编写判断逻辑:

// 统一配置所有分支规则:判断条件、异步取值方法、赋值逻辑
var taskConfigs = new List<(bool IsEnabled, Func<Task<string>> GetValue, Action<string> SetValue)>
{
    (myCondition, getAsync, val => result.foo = val),
    (myOtherCondition, getAsync2, val => result.bar = val)
};

// 过滤符合条件的分支,并行执行所有任务
await Task.WhenAll(taskConfigs
    .Where(config => config.IsEnabled)
    .Select(async config => config.SetValue(await config.GetValue()))
);

对齐原代码行为的兼容方案

如果需要严格保留原代码「所有任务全部完成后才统一赋值」的特性(避免部分任务先完成提前赋值引发的并发问题),可以使用以下写法:

var pendingTasks = new List<(Task<string> ValueTask, Action<string> SetValue)>();

if (myCondition)
{
    pendingTasks.Add((getAsync(), val => result.foo = val));
}
if (myOtherCondition)
{
    pendingTasks.Add((getAsync2(), val => result.bar = val));
}

// 先等待所有任务执行完成
await Task.WhenAll(pendingTasks.Select(t => t.ValueTask));

// 统一批量赋值,和原代码行为100%一致
foreach (var taskItem in pendingTasks)
{
    // 此处await不会产生等待,任务已经执行完成
    taskItem.SetValue(await taskItem.ValueTask);
}

内容的提问来源于stack exchange,提问作者jmn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 21:36:05