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

如何确保Azure Blob文件上传完成并获取上传进度?

确保Azure Blob上传完成及获取上传进度

一、确保上传操作彻底完成

你的代码中已经使用await blobClient.UploadAsync(...),理论上该方法会等待上传操作完全完成后才返回,但仍出现立即访问找不到的情况,可从以下几点排查解决:

1. 处理异地冗余存储的同步延迟

如果你的存储账户使用异地冗余存储(GRS/RA-GRS),次要区域的数据同步存在秒级延迟(极端情况可能更长)。若读取请求被路由到次要区域,就会出现上传完成但读取不到的情况。
解决办法:上传完成后主动验证Blob存在,必要时添加重试逻辑:

// 上传后主动确认Blob状态
var exists = await blobClient.ExistsAsync();
if (!exists)
{
    // 循环重试3次,每次间隔1秒
    for (int i = 0; i < 3; i++)
    {
        await Task.Delay(1000);
        exists = await blobClient.ExistsAsync();
        if (exists) break;
    }
}
return exists;

2. 避免异步调用的同步阻塞问题

如果调用PutBlobAsync时使用Result或Wait()等同步阻塞方式,可能导致异步操作未真正完成就执行后续逻辑。必须始终用await调用该方法:

// 正确方式
var success = await PutBlobAsync("container", "blob", content);
// 错误方式(可能导致上传未完成)
var success = PutBlobAsync("container", "blob", content).Result;

3. 验证Blob名称一致性

Azure Blob存储对名称大小写不敏感但保留大小写,若后续访问时的Blob名称与上传时大小写不一致,可能出现找不到的情况。确保前后使用的blobName完全一致。

二、获取上传进度状态

可以通过BlobUploadOptions的ProgressHandler属性实现上传进度跟踪,修改后的代码如下:

public async Task<bool> PutBlobAsync(string containerName, string blobName, byte[] content, bool allowOverwrite = false, string contentType = null, IProgress<long> progress = null)
{
    try
    {
        var containerClient = CreateAndGetContainer(containerName);
        var blobClient = containerClient.GetBlobClient(blobName);

        var blobUploadOptions = new BlobUploadOptions();

        if (!String.IsNullOrEmpty(contentType))
            blobUploadOptions.HttpHeaders = new BlobHttpHeaders { ContentType = contentType };

        if (!allowOverwrite)
            blobUploadOptions.Conditions = new BlobRequestConditions { IfNoneMatch = ETag.All };

        // 设置进度回调
        if (progress != null)
        {
            blobUploadOptions.ProgressHandler = new Progress<long>(bytesTransferred =>
            {
                progress.Report(bytesTransferred);
            });
        }

        // 直接用content初始化MemoryStream,简化代码
        using (var stream = new MemoryStream(content))
        {
            await blobClient.UploadAsync(stream, blobUploadOptions);
        }

        // 主动确认Blob存在
        var exists = await blobClient.ExistsAsync();
        if (!exists)
        {
            for (int i = 0; i < 3; i++)
            {
                await Task.Delay(1000);
                exists = await blobClient.ExistsAsync();
                if (exists) break;
            }
        }

        return exists;
    }
    catch (RequestFailedException e)
    {
        Logger.Error(e, "PutBlobAsync");

        switch (e.Status)
        {
            case (int)HttpStatusCode.NotFound:
            case (int)HttpStatusCode.PreconditionFailed:
                return false;
        }
        throw;
    }
}

调用时传入进度跟踪实例即可实时获取进度:

var progress = new Progress<long>(bytes =>
{
    Console.WriteLine($"已上传 {bytes} 字节,总大小 {content.Length} 字节");
});

var success = await PutBlobAsync("my-container", "my-blob.txt", content, false, "text/plain", progress);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 01:57:36