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

Angular调用C# PowerBI API时请求持续Pending状态求助

解决Angular调用C# API请求Pending的问题

嘿,我看到你遇到了API请求一直Pending的问题,十有八九是C#代码里的异步处理不当导致的死锁,咱们一起来捋一捋~

核心问题:同步阻塞异步操作引发死锁

你的getToken方法里用了token.Result来同步获取AcquireTokenAsync的结果,这在ASP.NET环境下非常容易触发死锁:

  • AcquireTokenAsync是异步方法,执行时会释放当前线程
  • 调用.Result会阻塞当前线程,等待异步操作完成
  • 异步操作结束后需要回到原ASP.NET上下文,但这个上下文已经被阻塞的线程占用,形成死锁,导致API一直挂起无法返回

修复方案:全链路异步化

我们需要把所有涉及异步操作的方法改成异步模式,全程用await替代同步阻塞调用:

修改后的C# API代码

private static readonly string Tenant = "https://login.microsoftonline.com/{azure.tenant}/";
private static readonly string Resource = "https://analysis.windows.net/powerbi/api";

// 改为异步方法,返回Task<string>
private async Task<string> getToken()
{
    var authContext = new AuthenticationContext(Tenant);
    var clientCredential = new ClientCredential(AppId, AppSecret);
    var token = await authContext.AcquireTokenAsync(Resource, clientCredential);
    return token.AccessToken;
}

// 同理改为异步方法,返回Task<PowerBIClient>
private async Task<PowerBIClient> getPBIClient()
{
    var token = new TokenCredentials(await getToken(), "Bearer");
    return new PowerBIClient(new Uri("https://api.powerbi.com/"), token);
}

public async Task<ODataResponseListReport> getReportsAsync(string ws)
{
    // 异步获取PowerBIClient实例
    PowerBIClient pbiClient = await getPBIClient();
    var reports = await pbiClient.Reports.GetReportsInGroupAsync(ws);
    return reports;
}

public async Task<ReportEmbeddingData> getReportEmbeddingDataAsync(string ws, string rep)
{
    PowerBIClient pbiClient = await getPBIClient();
    var report = await pbiClient.Reports.GetReportInGroupAsync(ws, rep);
    var embedUrl = report.EmbedUrl;
    var reportName = report.Name;
    
    GenerateTokenRequest genTokenReqParam = new GenerateTokenRequest(accessLevel: "view");
    string embedToken = (await pbiClient.Reports.GenerateTokenInGroupAsync(ws, rep, genTokenReqParam)).Token;
    
    return new ReportEmbeddingData
    {
        reportId = rep,
        reportName = reportName,
        embedUrl = embedUrl,
        accessToken = embedToken
    };
}

额外注意:控制器方法也要保持异步

确保你的API控制器调用上述方法时也是异步的,比如:

[HttpGet]
public async Task<IActionResult> Get(string ws)
{
    var result = await getReportsAsync(ws);
    return Ok(result);
}

Angular代码小优化

虽然你说TS代码没问题,但可以用ES6模板字符串让参数拼接更清晰易读:

getReports(){
  this.http.get(`http://localhost:44391/api/Auth?ws=${this.workspaceId}`)
    .subscribe((response) => {
      this.reportArray = response;
      console.log(this.reportArray);
    });
}

这样修改后,异步操作会正确释放上下文,避免死锁,你的API请求应该就能正常返回结果啦~

内容的提问来源于stack exchange,提问作者Luís Basto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:56:51