泛型方法+方法引用可构建类型安全异步分发器:通过Func<TInput, Task<TOutput>>契约明确输入输出,编译期锁定类型;直接传入方法组(如UserService.CreateUser)避免闭包与冗余封装;分发方法仅调度不掺业务,支持取消令牌与CPU/IO路径分离。

直接用泛型方法 + 方法引用,就能绕过冗余封装、避免运行时类型转换,快速搭出类型安全的异步任务分发器。核心是让编译器在编译期就锁定参数和返回类型,不靠反射、不靠 object 中转,也不依赖外部容器。
定义统一的异步任务契约
先声明一个泛型委托,明确“输入→异步执行→输出”的契约:
-
Func<TInput, Task<TOutput>>:最轻量,适配绝大多数业务方法(如
async Task<Order> CreateOrder(OrderRequest req)) - 避免用
Task或object作返回,否则会丢失类型信息,后续无法做编译期校验 - 不额外包装成自定义接口(如
IAsyncHandler<TIn, TOut>),除非有跨切面强需求(日志/熔断等),否则徒增抽象层级
用方法引用直连业务逻辑
业务方法写好后,直接以方法组形式传入,无需 lambda 包裹或 new 委托实例:
-
DispatchAsync<UserRequest, UserResponse>(UserService.CreateUser)✅ -
DispatchAsync<UserRequest, UserResponse>(req => UserService.CreateUser(req))❌(多一层闭包,且可能捕获变量) - 编译器自动推导泛型参数,调用处可省略显式类型标注:
DispatchAsync(UserService.CreateUser)
泛型分发方法实现要点
分发方法本身要足够薄,只做调度不掺业务:
- 签名示例:
public static async Task<TOutput> DispatchAsync<TInput, TOutput>(Func<TInput, Task<TOutput>> handler, TInput input) - 内部不做 await 后续处理(如重试、降级),那是策略层的事;只负责调用并传播异常
- 若需上下文隔离(如取消令牌、请求 ID 透传),通过可选参数接收:
CancellationToken ct = default,而非硬编码进泛型参数
配合 Task.Run 做 CPU 密集型任务分流
对非 IO 但耗时的操作(如 Excel 解析、图像缩略),用泛型方法+Task.Run无缝切换线程:
DispatchCpuBound<ImageData, Thumbnail>(ImageProcessor.GenerateThumbnail)- 内部实现为:
return await Task.Run(() => handler(input)),泛型确保输入输出类型全程不丢失 - 与 IO 异步路径完全分离,避免
async void或阻塞式.Result的陷阱

















