如何用C#按地域获取Azure资源成本?代码停滞问题排查
问题:C#调用Azure Consumption API获取地域资源成本时程序陷入停滞
我尝试使用C#按地域获取Azure资源成本,编写了如下代码:
var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(<clientid>, <secret>, <tenantid>, AzureEnvironment.AzureGlobalCloud); var consumptionClient = new ConsumptionManagementClient(credentials) { SubscriptionId = <subscription_id>}; var usageDetails = consumptionClient.UsageDetails.List("filter=properties/usageStart eq '2024-02-01' and properties/usageEnd eq '2022-02-28' and properties/instanceLocation eq 'West Europe'"); foreach (var usageDetail in usageDetails) { Console.WriteLine($"Resource: {usageDetail.Id}, Cost: {usageDetail.PretaxCost}"); }
但程序在执行到var usageDetails这一行时陷入停滞,始终无法继续执行后续代码。请问该问题可能的原因是什么?如何才能让代码正常运行?
可能的原因及解决方案
1. 时间范围逻辑错误
过滤条件中usageStart(2024-02-01)晚于usageEnd(2022-02-28),时间范围完全倒置,API处理这种不合理条件时可能陷入无效查询,导致程序停滞。
修复方式:调整时间范围,确保起始时间早于结束时间:
var filter = "filter=properties/usageStart eq '2022-02-01' and properties/usageEnd eq '2022-02-28' and properties/instanceLocation eq 'West Europe'"; var usageDetails = consumptionClient.UsageDetails.List(filter);
2. 未处理分页导致阻塞
Azure Consumption API的UsageDetails.List返回分页结果,直接遍历大量数据时,同步方法易因加载数据过多出现无响应。
修复方式:改用异步方法手动处理分页,同时确保使用最新版SDK:
var usageDetails = new List<UsageDetail>(); string nextLink = null; do { var result = await consumptionClient.UsageDetails.ListAsync(filter, nextLink: nextLink); usageDetails.AddRange(result); nextLink = result.NextPageLink; } while (!string.IsNullOrEmpty(nextLink)); foreach (var usageDetail in usageDetails) { Console.WriteLine($"Resource: {usageDetail.Id}, Cost: {usageDetail.PretaxCost}"); }
3. 权限不足或API限流
服务主体缺少Cost Management Reader/Reader权限时,API可能静默挂起;同时Azure API有调用频率限制,超过限制会触发限流导致请求阻塞。
修复方式:
- 在Azure门户给服务主体分配
Cost Management Reader角色,确保其能读取消费数据。 - 添加异常捕获,排查API调用错误:
try { var usageDetails = consumptionClient.UsageDetails.List(filter); foreach (var item in usageDetails) { Console.WriteLine($"Resource: {item.Id}, Cost: {item.PretaxCost}"); } } catch (CloudException ex) { Console.WriteLine($"API调用错误: {ex.Message}, {ex.Response.Content}"); } catch (Exception ex) { Console.WriteLine($"程序异常: {ex.Message}"); }
4. 网络或环境问题
运行环境无法连接Azure服务(如防火墙阻断请求),会导致请求一直处于等待状态,表现为程序停滞。
修复方式:
- 测试运行环境到
management.azure.com的网络连通性。 - 若使用代理,在代码中配置代理:
var handler = new HttpClientHandler { Proxy = new WebProxy("http://your-proxy-address:port"), UseProxy = true }; var httpClient = new HttpClient(handler); var consumptionClient = new ConsumptionManagementClient(credentials, httpClient) { SubscriptionId = <subscription_id>};
内容的提问来源于stack exchange,提问作者Melissa
相关产品推荐
相关产品推荐

