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

如何将三参数Action<T,T,T>列表转换为顺序执行的Task列表

改造实现方案

从C# 7.1开始,控制台应用的Main方法原生支持async Task异步入口,不需要额外做阻塞等待即可直接使用async/await语法,完整改造代码如下:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program
{
    // 原有Action方法定义保持不变即可
    static void Action1(string a, string b, string c) => Console.WriteLine($"Action1执行,入参:{a} {b} {c}");
    static void Action2(string a, string b, string c) => Console.WriteLine($"Action2执行,入参:{a} {b} {c}");
    static void Action3(string a, string b, string c) => Console.WriteLine($"Action3执行,入参:{a} {b} {c}");
    static void Action4(string a, string b, string c) => Console.WriteLine($"Action4执行,入参:{a} {b} {c}");
    static void Action5(string a, string b, string c) => Console.WriteLine($"Action5执行,入参:{a} {b} {c}");

    static async Task Main(string[] args)
    {
        var actionList = new List<Action<string, string, string>>()
        {
            Action1,
            Action2,
            Action3,
            Action4,
            Action5
            // 可继续追加同签名Action
        };

        foreach (var action in actionList)
        {
            // 直接获取当前Action的方法名,和原逻辑完全一致
            Console.WriteLine($"Invoking action: {action.Method.Name} ...");
            
            // 顺序执行:await会暂停当前循环,直到当前任务执行完成才会进入下一轮
            // 同步Action用Task.Run包装为Task执行,保持异步执行特性
            await Task.Run(() => action.Invoke("Hello", "World", "!"));
            
            // 原有其他同步逻辑保持不变,会等当前Action执行完成后再运行
            Console.WriteLine($"{action.Method.Name} 执行完成");
        }
    }
}
核心逻辑说明
  • 方法名获取:直接通过委托自带的Method.Name属性取值,和原同步代码写法完全一致,不需要额外适配
  • 顺序执行保证:使用原生foreach循环+await的组合,每次循环会等待当前Task执行完毕后才会启动下一个任务,完全杜绝并行执行。注意不要使用List<T>.ForEach()方法,它是同步遍历实现,传入异步lambda会生成async void,既无法捕获异常也不能等待执行完成,会出现执行顺序错乱的问题;也不要用Task.WhenAll,该方法会一次性启动所有任务再等待全部完成,不符合顺序执行要求
  • 参数一致性:调用Action时传入的三个参数和原代码完全一致,为"Hello"、"World"、"!",不需要修改参数传递逻辑
  • 旧框架兼容:如果使用不支持async Task Main的旧版.NET Framework,可以把异步执行逻辑抽到单独的async Task方法中,在同步Main里用GetAwaiter().GetResult()等待执行即可,示例代码如下:
// 旧框架兼容写法
static void Main(string[] args)
{
    RunAllActions().GetAwaiter().GetResult();
}

static async Task RunAllActions()
{
    // 把前面foreach循环的逻辑放到这里即可
}
  • 后续扩展:如果后续需要把列表中的方法替换为异步实现(返回Task的同签名方法),只需要把列表类型从List<Action<string, string, string>>改为List<Func<string, string, string, Task>>,循环内直接写await action("Hello", "World", "!")即可,其他逻辑不需要改动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 15:42:10