如何解决CloudBlob.CopyState 在直接账户到账户复制完成后为空
编辑:扩展代码示例以显示如何加载 destinationBlob
。
我们正在使用直接帐户到帐户复制来传输一组 blob。因为在进程开始时属性会被覆盖,所以我们会在一个时间间隔内监视目标 blob,然后在复制完成时设置属性。大多数情况下,此过程运行良好。
但是,对于这些 blob 中的几个,目标 blob 上没有复制状态(CloudBlob.copyState
是 null
)。这些 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());
,
我能想到两种解决方法。
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 举报,一经查实,本站将立刻删除。