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

.NET Core测试桩同步执行异步Expression<Action<T>>方法的方案

解决异步方法在BackgroundTasksServiceStub中的同步执行问题

你的测试桩当前只处理了同步方法的调用,当遇到async Task类型的异步方法时,直接编译执行Action<T>不会等待异步任务完成,导致任务在后台运行,进而引发异常或不符合预期的测试行为。

修改思路是:在桩服务中识别目标方法是否返回Task或Task<T>,如果是异步方法,就编译成返回Task的委托并同步等待其完成;如果是同步方法,保持原有逻辑不变。

修改后的代码如下:

public class BackgroundTasksServiceStub : IBackgroundTasksService
{
    private readonly IServiceProvider _serviceProvider;

    public BackgroundTasksServiceStub(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public void RunBackgroundTask<T>(Expression<Action<T>> methodCall)
    {
        var service = _serviceProvider.GetService<T>();
        if (service == null)
            return;

        // 解析表达式获取目标方法信息
        if (methodCall.Body is MethodCallExpression methodCallExpr)
        {
            var methodInfo = methodCallExpr.Method;
            var returnType = methodInfo.ReturnType;

            // 判断是否是异步方法(返回Task或Task<T>)
            if (returnType == typeof(Task) || (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>)))
            {
                // 编译为Func<T, Task>并同步等待任务完成
                var func = Expression.Lambda<Func<T, Task>>(methodCall.Body, methodCall.Parameters).Compile();
                func(service).GetAwaiter().GetResult();
                return;
            }
        }

        // 同步方法按原有逻辑执行
        var method = methodCall.Compile();
        method(service);
    }
}

关键说明

  • 解析传入的Expression<Action<T>>,提取调用的方法信息
  • 通过判断方法返回类型是否为Task或泛型Task<T>,识别异步方法
  • 对异步方法,将表达式重新编译为Func<T, Task>委托,调用后使用GetAwaiter().GetResult()同步等待任务完成(避免用.Wait(),防止上下文死锁)
  • 同步方法保持原有执行逻辑,不影响原有测试场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 19:28:10