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

Azure Functions高负载下DryIOC超时:调整超时与获取异常详情

问题

我的Azure Functions在低负载下运行正常,但高负载时频繁触发DryIOC超时(非必现),异常信息如下:

---> Microsoft.Azure.WebJobs.Script.Workers.Rpc.RpcException: Result: Failure
Exception: DryIoc.ContainerException: code: Error.WaitForScopedServiceIsCreatedTimeoutExpired;
message: DryIOC等待"另一方"创建作用域或单例服务已达3000个时间周期仍未完成。
您可以调用`exception.TryGetDetails(container)`获取有问题的服务注册详情。
该错误意味着:要么"另一方"是已启动但无法在指定时间内完成服务创建的并行线程;
更可能的情况是"另一方"为同一线程,存在未检测到的递归依赖,
或者作用域服务创建时抛出异常但被捕获,而您又尝试再次解析该失败的服务。
出于上述原因,DryIOC设置了超时以防止无限等待。
您可以通过`Scope.WaitForScopedServiceIsCreatedTimeoutTicks=NewNumberOfTicks`修改默认超时时间
...(省略后续栈信息)

一、延长DryIOC超时时间

DryIOC的默认超时由Scope.WaitForScopedServiceIsCreatedTimeoutTicks控制,单位为时钟周期(Tick),1毫秒等于10000个Tick。默认值对应300毫秒左右,高负载下可适当调大:

在Azure Functions Worker的启动配置(Program.cs)中修改:

using DryIoc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(builder =>
    {
        // 添加全局异常中间件(可选,用于后续捕获详情)
        builder.UseMiddleware<ExceptionHandlingMiddleware>();
    })
    .ConfigureServices(services =>
    {
        // 配置完成后获取DryIOC容器实例
        services.PostConfigure<IContainer>(container =>
        {
            // 设置超时为10秒(转换为Tick)
            container.ScopeContext.WaitForScopedServiceIsCreatedTimeoutTicks = TimeSpan.FromSeconds(10).Ticks;
        });
    })
    .Build();

host.Run();

二、获取问题服务注册详情

通过TryGetDetails方法可获取导致超时的服务依赖链信息,需在捕获DryIoc.ContainerException时调用:

  1. 添加全局异常处理中间件
    创建中间类捕获并处理异常:
using DryIoc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Middleware;
using Microsoft.Extensions.Logging;

public class ExceptionHandlingMiddleware : IFunctionsWorkerMiddleware
{
    private readonly ILogger<ExceptionHandlingMiddleware> _logger;
    private readonly IContainer _container;

    public ExceptionHandlingMiddleware(ILogger<ExceptionHandlingMiddleware> logger, IContainer container)
    {
        _logger = logger;
        _container = container;
    }

    public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
    {
        try
        {
            await next(context);
        }
        catch (ContainerException ex) when (ex.Error == Error.WaitForScopedServiceIsCreatedTimeoutExpired)
        {
            // 获取服务注册详情
            var details = ex.TryGetDetails(_container);
            _logger.LogError(ex, "DryIOC超时问题详情:\n{Details}", details);
            throw; // 保留原异常抛出,或根据需求处理
        }
    }
}
  1. 详情说明
    TryGetDetails返回的内容包含:
  • 超时服务的类型
  • 完整的依赖注入链
  • 服务注册的生命周期类型(单例/作用域/瞬态)
    这些信息可直接定位递归依赖、服务创建缓慢或失败的根本原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:14:55