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

C#中如何条件性执行并行任务?解决未赋值及Created状态问题

处理C#条件性并行任务的正确方式

问题根源

你遇到的问题有两个核心点:

  1. 不进入if分支时,ccTask、cfTask未赋值,会触发编译错误或运行时空引用异常。
  2. 用new Task<T>创建的任务处于Created状态,未自动启动,会导致Task.WhenAll无限等待。

解决方案一:提前初始化默认已完成任务

最简洁高效的方式是在声明变量时直接赋值为已完成的任务,无需额外else分支,从根源避免未赋值问题:

// 初始化默认的已完成任务,确保变量始终有有效值
Task<StandardResponse<bool>> qcTask = service.ProcessQuestionsAndComments(inputData);
Task<StandardResponse<bool>> ccTask = Task.FromResult(new StandardResponse<bool> { Status = HttpStatusCode.OK });
Task<StandardResponse<bool>> cfTask = Task.FromResult(new StandardResponse<bool> { Status = HttpStatusCode.OK });

if (StatusId == (int)STATUS.COMPLETED)
{
    // 覆盖默认任务,替换为实际需要并行执行的任务
    ccTask = service.ProcessCompletedStatus(inputData);
    cfTask = service.ProcessCompletedFile(inputData);
}

await Task.WhenAll(qcTask, ccTask, cfTask).ConfigureAwait(false);

这种方式的优势:

  • 代码结构更简洁,无需额外分支处理
  • Task.FromResult直接返回已完成的Task实例,性能开销极低
  • 彻底避免空引用和未赋值问题

解决方案二:在else分支中处理默认任务

如果坚持保留else分支,不要使用new Task<T>创建任务(它不会自动启动),推荐以下两种方式:

方式A:使用Task.FromResult(推荐)

Task<StandardResponse<bool>> qcTask;
Task<StandardResponse<bool>> ccTask;
Task<StandardResponse<bool>> cfTask;

qcTask = service.ProcessQuestionsAndComments(inputData);
if (StatusId == (int)STATUS.COMPLETED)
{
    ccTask = service.ProcessCompletedStatus(inputData);
    cfTask = service.ProcessCompletedFile(inputData);
}
else
{
    // 直接返回已完成任务,无需手动启动
    ccTask = Task.FromResult(new StandardResponse<bool> { Status = HttpStatusCode.OK });
    cfTask = Task.FromResult(new StandardResponse<bool> { Status = HttpStatusCode.OK });
}

await Task.WhenAll(qcTask, ccTask, cfTask).ConfigureAwait(false);

方式B:手动启动new创建的任务(不推荐)

如果一定要用new Task<T>,必须手动调用Start()启动任务,否则任务永远不会执行:

else
{
    ccTask = new Task<StandardResponse<bool>>(() => new StandardResponse<bool> { Status = HttpStatusCode.OK });
    cfTask = new Task<StandardResponse<bool>>(() => new StandardResponse<bool> { Status = HttpStatusCode.OK });
    // 必须手动启动任务,否则会处于Created状态
    ccTask.Start();
    cfTask.Start();
}

这种方式不推荐,因为Task.FromResult更简洁高效,new Task<T>通常用于高级任务调度场景,日常并行处理用前者更合适。

额外优化建议

如果条件性任务数量不固定,可以用List<Task>动态管理任务,扩展性更好:

var tasks = new List<Task<StandardResponse<bool>>>();
tasks.Add(service.ProcessQuestionsAndComments(inputData));

if (StatusId == (int)STATUS.COMPLETED)
{
    tasks.Add(service.ProcessCompletedStatus(inputData));
    tasks.Add(service.ProcessCompletedFile(inputData));
}
else
{
    tasks.Add(Task.FromResult(new StandardResponse<bool> { Status = HttpStatusCode.OK }));
    tasks.Add(Task.FromResult(new StandardResponse<bool> { Status = HttpStatusCode.OK }));
}

await Task.WhenAll(tasks).ConfigureAwait(false);

内容的提问来源于stack exchange,提问作者Kiran Ramchandra Parab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:55:23