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

如何无需改造调用链为异步,同步调用ApplicationTokenProvider?

Ah, I’ve been there—dealing with that frustrating deadlock when mixing async and sync code in ASP.NET MVC. Let’s break down what’s happening and how to fix it without rewriting your entire call chain.

The root issue here is the ASP.NET Synchronization Context. When you call .Result on an async method in an MVC controller, the context blocks waiting for the async task to complete. But the LoginSilentAsync method tries to resume execution on that same synchronization context once it’s done—creating a circular wait (the context is blocked waiting for the task, and the task is waiting for the context to be free). That’s why it works in your test environment (which probably doesn’t have a synchronization context, like a console app) but hangs in MVC.

Here are a couple of reliable ways to make this work synchronously without refactoring the whole chain:

1. Wrap the async call in Task.Run

This pushes the async operation onto a thread pool thread, which doesn’t use the ASP.NET synchronization context. That breaks the deadlock cycle:

public void Authenticate() 
{ 
    // Run the async operation on a thread pool thread to avoid synchronization context deadlock
    var serviceCreds = Task.Run(() => 
        ApplicationTokenProvider.LoginSilentAsync(TenantId, ApplicationId, Secret)
    ).Result; 

    var monitorClient = new MonitorManagementClient(serviceCreds) 
    { 
        SubscriptionId = SubscriptionId.ToString() 
    }; 

    MonitorClient = monitorClient; 
}

2. Use GetAwaiter().GetResult() with ConfigureAwait(false)

ConfigureAwait(false) tells the async method not to try resuming on the original synchronization context, and GetAwaiter().GetResult() avoids the exception wrapping that .Result does (it throws the original exception directly instead of an AggregateException):

public void Authenticate() 
{ 
    var serviceCreds = ApplicationTokenProvider.LoginSilentAsync(TenantId, ApplicationId, Secret)
        .ConfigureAwait(false)
        .GetAwaiter()
        .GetResult(); 

    var monitorClient = new MonitorManagementClient(serviceCreds) 
    { 
        SubscriptionId = SubscriptionId.ToString() 
    }; 

    MonitorClient = monitorClient; 
}

A quick heads-up: While these fixes work for your immediate problem, Microsoft recommends using async/await all the way up the call chain for long-term maintainability and scalability. But if refactoring the entire chain isn’t feasible right now, either of these approaches should unblock you.

内容的提问来源于stack exchange,提问作者Chris B. Behrens

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:19:12