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

Azure Blob容器遍历异常:控制台应用调用ListBlobsSegmentedAsync后进程以代码0终止

问题根源分析

你的问题核心出在异步方法的调用与等待逻辑上:

  • 你定义的GetBlobFileProperties是async void类型,这种返回值主要用于UI事件处理场景,在控制台应用中调用时,主线程不会等待它的异步操作完成。
  • Main方法是同步执行的,调用analyser.GetBlobFileProperties()后会立刻执行完毕,导致整个进程直接退出(返回code 0),此时ListBlobsSegmentedAsync的异步操作还没来得及完成就被终止了。
解决方案

我们需要调整异步方法的定义和调用方式,确保主线程等待异步操作完成,同时完善Blob的分段遍历逻辑(避免只获取第一页数据):

1. 修改异步方法的返回类型

把async void改成async Task,这样我们可以在调用时用await等待它执行完成:

public class AzureStorageAnalyser
{
    public async Task GetBlobFileProperties()
    {
        try
        {
            string storageConnection = "DefaultEndpointsProtocol=https;AccountName=****;AccountKey=****;EndpointSuffix=core.windows.net";
            CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(storageConnection);
            CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
            CloudBlobContainer blobContainer = cloudBlobClient.GetContainerReference("users");
            
            BlobContinuationToken blobContinuationToken = null;
            List<string> fileUris = new List<string>();

            // 循环获取所有分段的Blob,直到没有更多数据
            do
            {
                // 使用完整重载确保扁平化列出所有Blob(不显示虚拟目录)
                var resultSegment = await blobContainer.ListBlobsSegmentedAsync(
                    prefix: null,
                    useFlatBlobListing: true,
                    blobListingDetails: BlobListingDetails.None,
                    maxResults: null,
                    currentToken: blobContinuationToken,
                    options: null,
                    operationContext: null);
                
                blobContinuationToken = resultSegment.ContinuationToken;

                foreach (var blobItem in resultSegment.Results)
                {
                    // 确保处理的是Blob而非虚拟目录
                    if (blobItem is CloudBlockBlob blob)
                    {
                        fileUris.Add(blob.StorageUri.PrimaryUri.ToString());
                        Console.WriteLine($"已获取Blob: {blob.Name}");
                    }
                }
            } while (blobContinuationToken != null);

            Console.WriteLine($"共获取到 {fileUris.Count} 个Blob资源");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"发生错误: {ex.Message}");
            // 打印堆栈信息便于排查深层问题
            Console.WriteLine(ex.StackTrace);
        }
    }
}

2. 修改Main方法为异步入口

从C# 7.1开始,控制台应用支持async Task Main作为入口方法,这样我们可以直接等待异步操作完成:

static async Task Main(string[] args)
{
    AzureStorageAnalyser analyser = new AzureStorageAnalyser();
    await analyser.GetBlobFileProperties();

    // 可选:添加等待输入,避免程序执行完后窗口立刻关闭
    Console.WriteLine("\n按任意键退出...");
    Console.ReadKey();
}
额外说明
  • 我添加了do-while循环来处理Blob的分页返回,当容器中Blob数量较多时,ListBlobsSegmentedAsync会分段返回结果,只调用一次只能拿到第一页数据。
  • 增加了CloudBlockBlob的类型判断,避免处理容器中的虚拟目录(如果存在的话)。
  • 在catch块中添加了堆栈信息打印,方便你排查可能的存储账户连接、权限等深层问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 12:27:38