CloudBlobContainer.ListBlobs() - 使用ToList()来降低事务成本

时间:2011-10-03 15:18:44

标签: c# azure azure-storage azure-storage-blobs

我有两个代码示例:

var container = new CloudBlobContainer("address");
var blobs = container.ListBlobs();
foreach (var blob in blobs)
{
    //Do somthing
}

和此:

var container = new CloudBlobContainer("address");
var blobs = container.ListBlobs().ToList();
foreach (var blob in blobs)
{
     //Do somthing
}

第二个例子是否会“以交易方式”给予任何好处? 在每个示例中对blob存储进行了多少次事务处理?

1 个答案:

答案 0 :(得分:4)

修改:此问题似乎与blog post by Martin Ingvar Kofoed Jensen有关。此问题与该问题之间的区别在于对.Where(...).SingleOrDefault()的调用。因为LINQ是惰性求值的,所以在Container.ListBlobs()阶段它仍然是IEnumerable并且还没有调用REST API(没有检索到数据)。一旦结果操作发生(例如ToList()SingleOrDefault()),就会下载数据。由于在以下代码中循环内的惰性列表上调用了非延迟操作,因此每次循环迭代都会产生一个事务:

foreach (string filePath in allFilesInStartFolder)
{
    string fileHash = GetFileHashFromCache(filePath, lastSync);

    /* Checking for added files */
    var blob = blobs.Where(b => b.LocalPath == filePath).SingleOrDefault();
    // ^^ This is a non-lazy op on a lazy evalution, so it causes a REST call.
    ....
}

关于实际编写的问题:两个代码片段都会产生single transaction(最多5,000个blob)。我在LinqPad / Fiddler中测试了两个代码段,我只看到一个single API call来生成blob列表(用{mystore}替换了我们的存储名称):

https://{mystore}.blob.core.windows.net/
    {mystore}?restype=container&comp=list&delimiter=%2F&timeout=90

根据List Blobs REST API的文档,一次通话最多可返回5,000个结果。因此,如果要列出整个容器中的所有blob,最多需要(#blobs / 5000)事务。