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

基于字符串类型通过反射调用泛型异步方法填充列表的问题

反射调用异步泛型方法的正确实现及性能分析

一、正确实现方式

你遇到的报错核心原因是:method.Invoke返回的是object类型,实际对应Task<IEnumerable<T>>,但编译器无法识别它是可await的Task,也不能直接将Task<IEnumerable<T>>赋值给IList。正确的处理步骤如下:

1. 调用方法并await Task

先将Invoke的结果转换为非泛型Task,等待任务完成后再提取结果:

// 调用泛型方法,返回Task对象
var task = (Task)method.Invoke(_sql, args)!;
// 等待异步任务完成
await task;

2. 提取任务结果并转换为集合

通过反射获取Task的Result属性,得到IEnumerable<T>实例,再将其元素添加到你创建的IList中:

// 获取Task的Result属性值(即IEnumerable<T>)
var resultProperty = task.GetType().GetProperty("Result")!;
IEnumerable resultEnumerable = (IEnumerable)resultProperty.GetValue(task)!;

// 将结果元素添加到IList中
foreach (var item in resultEnumerable)
{
    l.Add(item);
}

或者更直接的方式:如果不需要提前创建IList,可以直接将结果转换为IList(因为List<T>实现了IList接口):

var task = (Task)method.Invoke(_sql, args)!;
await task;
var result = task.GetType().GetProperty("Result")!.GetValue(task);
// 直接将IEnumerable<T>转为IList
l = (IList)result!;

二、反射调用的性能与高并发影响

1. 性能开销点

反射的性能损耗主要集中在两个环节:

  • 方法查找与筛选:GetMethods()+Where()+First()的组合会遍历类型的所有方法,耗时较高。
  • 泛型方法实例化:MakeGenericMethod()会动态生成泛型方法的具体实例,这一操作会产生额外的元数据和内存开销。

相比之下,Invoke本身的性能开销反而较小。

2. 高并发场景的影响

如果不做优化,在高并发场景下重复执行上述反射操作,会导致:

  • 大量的CPU时间消耗在方法查找和泛型实例化上。
  • 频繁的动态类型生成会增加GC压力,可能引发频繁垃圾回收。

3. 优化方案

最有效的优化方式是缓存泛型方法的MethodInfo实例,避免重复执行反射查找和实例化:

// 定义静态缓存字典,按类型缓存对应的MethodInfo
private static readonly System.Collections.Concurrent.ConcurrentDictionary<Type, MethodInfo> _queryAsyncMethodCache = new();

// 获取方法时优先从缓存读取
if (!_queryAsyncMethodCache.TryGetValue(type, out var cachedMethod))
{
    cachedMethod = _sql.GetType().GetMethods()
        .Where(c => c.Name == "QueryAsync" 
            && c.GetParameters()[1].ParameterType == typeof(DynamicParameters))
        .First()
        .MakeGenericMethod(type);
    _queryAsyncMethodCache.TryAdd(type, cachedMethod);
}
// 使用缓存的方法实例
var method = cachedMethod;

使用ConcurrentDictionary可以避免高并发场景下的锁竞争问题,进一步提升性能。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:18:29