Azure遍历Blob容器调用ToListAsync方法报错解决方案
报错原因
- 你使用的是Azure Blob Storage v12及以上版本的官方SDK,
blobContainer.GetBlobsAsync()方法返回的类型是AsyncPageable<BlobItem>,属于支持异步流式迭代的分页结果类型,和你当前调用的ToListAsync()方法不兼容:要么是项目未引入异步LINQ枚举对应的依赖包,要么是IDE自动误引用了EF Core等其他组件提供的同名ToListAsync扩展——这类扩展仅支持IQueryable类型,无法识别AsyncPageable的分页迭代逻辑,编译阶段可能不报错,但调用时就会触发运行时异常。 - 即使修复了方法兼容问题,直接对全量Blob结果调用
ToListAsync()会一次性拉取容器内所有Blob的元数据到内存,当容器内Blob数量较多时会产生极高的内存开销,不推荐在生产环境使用。
修复方法
优先使用SDK原生支持的await foreach语法遍历,不需要引入额外依赖,SDK会自动处理分页拉取逻辑,内存占用更稳定:
List<BlobClient> blobList = new List<BlobClient>(); // 直接异步遍历分页结果,SDK自动处理分页拉取 await foreach (BlobItem blobItem in blobContainer.GetBlobsAsync(prefix: "")) { BlobClient blob = blobContainer.GetBlobClient(blobItem.Name); // 读取Blob属性 Response<BlobProperties> propertiesResponse = await blob.GetPropertiesAsync(); BlobProperties properties = propertiesResponse.Value; // 按修改时间过滤 if (DateTimeOffset.Compare(properties.LastModified.ToUniversalTime(), transferBlobsModifiedSince.ToUniversalTime()) > 0) { blobList.Add(blob); } }
如果你确实需要先把所有BlobItem一次性转为List再处理,需要先给项目安装System.Linq.Async NuGet包,引入对应的LINQ异步命名空间后,原有写法就可以正常运行:
// 需先安装System.Linq.Async包,添加命名空间引用:using System.Linq; List<BlobItem> segment = await blobContainer.GetBlobsAsync(prefix: "").ToListAsync(); foreach (BlobItem blobItem in segment) { BlobClient blob = blobContainer.GetBlobClient(blobItem.Name); Response<BlobProperties> propertiesResponse = await blob.GetPropertiesAsync(); BlobProperties properties = propertiesResponse.Value; if (DateTimeOffset.Compare(properties.LastModified.ToUniversalTime(), transferBlobsModifiedSince.ToUniversalTime()) > 0) { blobList.Add(blob); } }
报错截图参考


内容的提问来源于stack exchange,提问作者Janet
相关产品推荐
相关产品推荐

