AzureStorage上でストレージ間コピーを行う時にシーケンシャルに行われない挙動があるので備忘として記載します。
このメソッドはBlobをコピーするのですが、非同期処理の振る舞いをするので注意が必要です。
実際にはコピー処理リクエストをAzureStorage側でキューイングしており、キューを順に処理しているので非同期のような振る舞いに見えてしまうようです。
複数のコピー処理を1回のリクエストで実施する場合はコピー対象ファイルの情報をフェッチしてステータスを確認する必要があります。
StorageCredentials sc_old = new StorageCredentials("ストレージアカウント名", "ストレージキー");
CloudStorageAccount account_old = new CloudStorageAccount(sc_old, false);
CloudBlobClient client_old = account_old.CreateCloudBlobClient();
CloudBlobContainer container_old = client_old.GetContainerReference("コンテナ名");
CloudBlockBlob blob_old = container_old.GetBlockBlobReference("ファイルパス");
//ファイルコピー先
StorageCredentials sc_new = new StorageCredentials("ストレージアカウント名", "ストレージキー");
CloudStorageAccount account_new = new CloudStorageAccount(sc_new, false);
CloudBlobClient client_new = account_new.CreateCloudBlobClient();
CloudBlobContainer container_new = client_new.GetContainerReference("コンテナ名");
CloudBlockBlob blob_new = container_new.GetBlockBlobReference("ファイルパス");
//URI形式でもSOURCE形式、どちらでもOK
blob_new.StartCopyFromBlob(new Uri(blob_old.Uri.ToString()));
//StartCopyFromBlob処理が非同期で動いてしまうので処理終了までwaitする。
while (true)
{
//対象コンテンツの状態をフェッチする。
blob_new.FetchAttributes();
if (blob_new.CopyState.Status != CopyStatus.Pending)
{
break;
}
System.Threading.Thread.Sleep(1000);
}
//プロパティにセットしたい値はコピーが終了してから実施
blob_new.Properties.ContentType = "text/xml";
blob_new.SetProperties();
※AzureSDK 2.2での実装です。
ストレージ内コピーは特に問題はないのですが、念のため上のような実装にしといたほうがいいかもしれません。
これは案外ハマリポイントですよ。
コメント