在性能方面使用CloudBlob.ExistsAsync vs catch StorageException.BlobNotFound?

时间:2018-02-19 15:21:47

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

我想从Azure Blob Storage下载一个可能尚不存在的文件。我正在寻找最可靠和最高效的方法来处理这个问题。为此,我发现两个选项都有效:

选项1:使用ExistsAsync()
持续时间:完成大约需要1000~1100ms。

if (await blockBlob.ExistsAsync())
{
    await blockBlob.DownloadToStreamAsync(ms);
    return ms;
}
else
{
    throw new FileNotFoundException();
}

选项2:抓住例外
持续时间:每次至少需要+ 1600毫秒。

try
{
    await blockBlob.DownloadToStreamAsync(ms);                
    return ms;      
}
catch (StorageException e)
{
    // note: there is no 'StorageErrorCodeStrings.BlobNotFound'
    if (e.RequestInformation.ErrorCode == "BlobNotFound")
        throw new FileNotFoundException();

    throw;
}

指标是通过webapi上的简单API调用完成的,它会使用上述函数并返回相应的消息。我通过Postman在这里手动测试了端到端场景。当然,这种方法有一些开销。但总结一下,似乎ExistsAsync()操作因此节省了至少500ms 。至少在我的本地机器上,在调试时。这有点引人注目,因为ExistsAsync()上的DoesServiceRequest属性似乎表明它是另一个需要进行的昂贵的http调用。

另外,ExistsAsync API docs没有说明它的用法或任何副作用。

根据穷人的测试,一个直截了当的结论将导致我选择否。 1,因为:

  • 它在debug / localhost中更快(捕获;没有说明在prod中编译)
  • 对我而言,它更有说服力,特别是因为ErrorCode也需要手动检查特定代码
  • 我会假设 ExistsAsync()操作就是出于这个原因

但这是我的实际问题:这是ExistsAsync()使用的正确插入吗?
例如。它存在的“为什么”=比仅仅捕获未找到的异常更有效率,特别是出于性能原因?

谢谢!

1 个答案:

答案 0 :(得分:3)

  

但这是我的实际问题:这是ExistsAsync()使用的正确插入吗?

您可以自己轻松查看the implementation

ExistsAsync()只是一个http调用的包装器,如果blob不在那里则会抛出一个http,在这种情况下返回false。否则True

我说要选择ExistsAsync,因为它似乎是最优化的方式,特别是如果你指望有时blob不存在的事实。 DownloadToStreamAsyncStorageException包装异常方面有more work to do,可能会进行更多清理。

  

我认为ExistsAsync()操作就是出于这个原因

考虑一下:有时你只想知道某个blob是否存在而不对内容感兴趣。例如,要发出警告,表示上传时会覆盖某些内容。在这种情况下使用ExistsAsync是一个很好的用例,因为使用DownloadToStreamAsync对于存在检查来说将是昂贵的,因为如果blob在那里它将下载内容。