微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

CloudBlob.CopyState 在直接账户到账户复制完成后为空

如何解决CloudBlob.CopyState 在直接账户到账户复制完成后为空

编辑:扩展代码示例以显示如何加载 destinationBlob

我们正在使用直接帐户到帐户复制来传输一组 blob。因为在进程开始时属性会被覆盖,所以我们会在一个时间间隔内监视目标 blob,然后在复制完成时设置属性。大多数情况下,此过程运行良好。

但是,对于这些 blob 中的几个,目标 blob 上没有复制状态(CloudBlob.copyStatenull)。这些 blob 事先不存在,它们是通过调用 CloudBlob.StartcopyAsync() 创建的。

这里有一些简化的代码来概述它的工作原理。

// Start copy operation
var operationId = await destinationBlob.StartcopyAsync(new Uri(sourceBlobUrlWithSas));

...

// In a separate process,check the status after a delay,then repeat on an interval
var destinationBlob = await _destinationContainer.GetBlobReferenceFromServerAsync(blobName);

if (destinationBlob.copyState.Status == copyStatus.Success) // <-- copyState is null
{
    // Set properties
}

Microsoft 文档指出,当没有复制状态时,copyState 将是 null,但在没有复制状态时不要概述。根据我自己的实验,目标​​ blob 似乎是立即创建的,并且在复制操作完成后,复制状态似乎仍保留在 blob 上一段时间。出现问题时,从开始复制到检查 copyState 只需几分钟。

可能是什么问题?是否有其他方法可以在目标 Blob 上设置属性

解决方法

这个问题最终是由于一个逻辑错误导致 blob 会被“触摸”导致复制状态被删除。关于复制状态数据生命周期的文档当然可以更好,但希望这种见解可以帮助遇到类似问题的其他人。

,

如果你想得到CopyState,我们首先需要运行CloudBlob.FetchAttributesAsync这个方法。该方法将从服务器返回 blob 的属性和元数据,然后我们可以获得 CopyState。详情请参阅here

例如(我使用包 Microsoft.Azure.Storage.Blob 进行测试)

            var storageAccount = CloudStorageAccount.Parse(connectionString);
            var cloudBlobClient = storageAccount.CreateCloudBlobClient();
            var cloudBlobContainer = cloudBlobClient.GetContainerReference("test");
            CloudBlob destBlob = cloudBlobContainer.GetBlobReference(soureblob.Name);
            string copyId = await destBlob.StartCopyAsync(uri);
            await destBlob.FetchAttributesAsync();

            Console.WriteLine("Status of copy operation: {0}",destBlob.CopyState.Status);
            Console.WriteLine("Completion time: {0}",destBlob.CopyState.CompletionTime);
            Console.WriteLine("Bytes copied: {0}",destBlob.CopyState.BytesCopied.ToString());
            Console.WriteLine("Total bytes: {0}",destBlob.CopyState.TotalBytes.ToString());

enter image description here

,

我能想到两种解决方法。

1.检查目标blob,无论copystatus是成功还是null,代码如下(这里我们使用的是null-conditional operator,所以不用担心CopyState是空):

if (destinationBlob.CopyState?.Status == CopyStatus.Success || destinationBlob.CopyState?.Status == null)
{
   //codes to set properties
}

2.另一种方法是创建a blob trigger azure function,它以目标容器为目标。这意味着当有任何 blob 上传/复制到目标容器时,该功能将被触发。所以你可以在函数中编写你的逻辑。

注意:您可以在代码中使用CloudBlockBlob代替Stream作为blob类型,这样您就可以使用CloudBlockBlob轻松添加属性.

public static void Run([BlobTrigger("samples-workitems/{name}")] CloudBlockBlob myBlob,string name,ILogger log)
{
   //other code
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。