如何提前启动Task并在后续阶段等待其完成?(C#异步编程)
解决提前启动异步任务并后续等待结果的问题
这问题我做性能优化时也踩过类似的坑,你的核心问题在于每次调用analyzer.Parse()都会创建一个全新的Task<IAnalyzerResult>实例——你前面启动的是第一个任务,后面await的却是另一个刚创建的新任务,完全没用到之前并行跑的那个,自然达不到节省时间的效果。
正确的做法是把启动的任务实例保存下来,后续直接等待这个已启动的任务,而不是重复调用Parse()。具体步骤如下:
- 先创建分析器实例
- 调用一次
Parse()获取任务对象,把它存在变量里(这是关键!) - 如果
Parse()返回的是冷任务(需要手动启动的Task实例),就调用它的Start()方法;如果是热任务(比如方法本身是async修饰的,内部已经开始执行),这一步可以跳过(强行调用Start()会报错) - 放心去执行你的其他处理逻辑,这段时间里Parse任务会在后台并行运行
- 等需要结果时,直接
await之前保存的那个任务变量即可
给你改好的代码示例:
var analyzer = new ExprAnalyzer(expr); // 核心:只调用一次Parse(),把返回的Task保存到变量中 Task<IAnalyzerResult> parseTask = analyzer.Parse(); // 仅当返回的是冷任务时需要这一步,根据实际情况调整 parseTask.Start(); // --- 这里放你要并行执行的其他操作 --- DoOtherProcessing(); ValidateInput(); PrepareResources(); // 等待之前启动的Parse任务完成,获取结果 IAnalyzerResult res = await parseTask; // 后续处理结果 ProcessAnalysisResult(res);
额外提醒一下:
- 如果你不确定
Parse()返回的是冷任务还是热任务,可以先测试:如果不调用Start()也能正常完成,那就是热任务,去掉Start()即可 - 确保
ExprAnalyzer的实例在并行执行期间是线程安全的,避免因为多线程访问导致的异常或数据错误
内容的提问来源于stack exchange,提问作者Prophet Lamb
相关产品推荐
相关产品推荐

