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

FindAsync搭配CancellationToken失效问题排查与解决

问题与解决:CancellationToken在MediatR Handler中不生效的排查

问题现象

测试从Activity表取数的Handler时,发现CancellationToken无效:在Postman中取消请求后,Handler里的for循环仍会完整执行5次,后续的FindAsync也能正常返回Activity对象,日志显示循环执行完成5秒后才触发数据库查询。起初按照相关建议调整了FindAsync的传参方式(将查询参数以数组形式传递,最后跟上CancellationToken),但问题依旧。

根因分析

核心问题在于控制器未将请求的CancellationToken传递给MediatR的Send方法,导致Handler接收的CancellationToken从未被触发取消信号,自然无法中断循环和数据库操作。

代码示例

测试用Handler代码(逻辑正确但因控制器传参问题失效)

public class Handler : IRequestHandler<Query, Result<Activity>>
{
    private readonly ReactivitiesContext _context;
    private readonly ILogger<Activity> _logger;

    public Handler(ReactivitiesContext context, ILogger<Activity> logger)
    {
        _context = context;
        _logger = logger;
    }

    public async Task<Result<Activity>> Handle(Query request,
        CancellationToken cancellationToken)
    {
        try
        {
            for (int i = 1; i <= 5; i++)
            {
                cancellationToken.ThrowIfCancellationRequested();
                await Task.Delay(1000, cancellationToken);
                _logger.LogInformation($"{i} second(s) have elapsed");
            }
        }
        catch (Exception)
        {
            _logger.LogInformation("Cancellation was done");
        }
        return Result<Activity>.Success(await _context.Activities.FindAsync(
            new object[] { request.Id }, cancellationToken));
    }
}

修正后的控制器代码(传递CancellationToken到MediatR)

[HttpGet("{id}")]
public async Task<IActionResult> GetActivity(Guid id, CancellationToken token)
{
    return ResultHandler(await Mediator.Send(new Details.Query { Id = id }, token));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:00:52