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

.NET Framework下Azure App Configuration连接异常问题求助

解决ASP.NET Framework请求期间连接Azure App Configuration挂起的问题

我之前也碰到过类似的场景,结合.NET Framework的同步上下文特性以及Azure Identity的实现逻辑,帮你梳理下问题根源和可行的解决方案:

为啥会出现挂起?

核心原因大概率是同步上下文死锁:.NET Framework的ASP.NET请求线程会绑定专属的SynchronizationContext,而Azure Identity的部分异步API如果被同步阻塞调用(比如用.Result、.Wait()),很容易导致线程卡住。而启动阶段(比如RouteConfig初始化)没有请求级别的同步上下文,所以调用正常;但请求期间触发的调用就会踩进死锁陷阱。

具体解决方案

1. 改用异步调用,避免同步阻塞

这是最根本的解决方式,把配置加载逻辑改成异步模式,全程用async/await,别再用同步阻塞的方式:

// 封装异步获取配置的方法
public async Task<IConfigurationRoot> LoadAppConfigAsync(string appConfigEndpoint)
{
    return await new ConfigurationBuilder()
        .AddAzureAppConfiguration(options =>
        {
            options.Connect(new Uri(appConfigEndpoint), new DefaultAzureCredential())
                   .Select(KeyFilter.Any, LabelFilter.Null);
        })
        .BuildAsync(); // 用BuildAsync替代同步的Build
}

然后在请求处理代码里(比如MVC控制器、Web Forms的异步页面方法)用await调用这个方法,确保请求处理方法本身是async的:

public async Task<ActionResult> MyAction()
{
    var config = await LoadAppConfigAsync("你的App Config地址");
    // 后续业务逻辑
    return View();
}

2. 临时剥离同步上下文(迫不得已时用)

如果实在没办法改成异步,也可以在调用Azure App Config的代码块中临时移除同步上下文,避免死锁:

var originalContext = SynchronizationContext.Current;
try
{
    // 临时清空同步上下文
    SynchronizationContext.SetSynchronizationContext(null);
    
    // 这里执行同步的配置加载
    var config = new ConfigurationBuilder()
        .AddAzureAppConfiguration(options =>
        {
            options.Connect(new Uri(appConfigEndpoint), new DefaultAzureCredential())
                   .Select(KeyFilter.Any, LabelFilter.Null);
        })
        .Build();
}
finally
{
    // 恢复原来的同步上下文
    SynchronizationContext.SetSynchronizationContext(originalContext);
}

3. 升级NuGet包版本

你目前用的Microsoft.Extensions.Configuration.AzureAppConfiguration 4.0.0和Azure.Identity 1.3.0都是比较旧的版本,后续版本针对.NET Framework的同步场景做了不少修复。建议升级到兼容.NET Framework 4.6.1+的最新稳定版:

  • Microsoft.Extensions.Configuration.AzureAppConfiguration 可升级到7.x系列
  • Azure.Identity 升级到1.10.x左右的稳定版

4. 预加载配置到静态缓存

如果不能在启动时初始化,那可以在应用启动阶段异步预加载配置到静态缓存,后续请求直接复用缓存内容,避免每次请求都重新连接:

public static class AppConfigCache
{
    private static readonly Lazy<Task<IConfigurationRoot>> _configLoader = 
        new Lazy<Task<IConfigurationRoot>>(() => LoadConfigAsync());

    public static Task<IConfigurationRoot> GetConfigAsync() => _configLoader.Value;

    private static async Task<IConfigurationRoot> LoadConfigAsync()
    {
        return await new ConfigurationBuilder()
            .AddAzureAppConfiguration(options =>
            {
                options.Connect(new Uri("你的App Config地址"), new DefaultAzureCredential())
                       .Select(KeyFilter.Any, LabelFilter.Null);
            })
            .BuildAsync();
    }
}

然后在Global.asax的Application_Start里触发预加载(启动阶段同步阻塞不会有死锁问题):

protected void Application_Start()
{
    // 其他初始化逻辑...
    AppConfigCache.GetConfigAsync().Wait();
}

后续请求里直接用await AppConfigCache.GetConfigAsync()获取缓存好的配置即可。

验证建议

  • 本地测试:用服务主体环境变量配置,在请求方法里调用异步加载逻辑,确认不再挂起
  • Azure环境测试:部署到启用系统托管标识的应用服务,验证请求期间的配置加载是否正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:46:56