使用 Azure 存储数据移动库防止多次传输操作
Prevent multiple transfer operations with Azure Storage Data Movement Library
我刚开始使用Azure Storage Data Movement Library (DML) having code similar to public DML sample code。用例是(增量地)将本地目录同步到 blob 存储多次,同时目录中的某些文件会不时更新。
UploadDirectoryOptions options = new UploadDirectoryOptions
{
SearchPattern = "*.*",
Recursive = false,
BlobType = BlobType.BlockBlob
};
// Register for transfer event.
DirectoryTransferContext context = new DirectoryTransferContext();
//only copy newer files - similar to AzCopy /XO /XN switches
//https://github.com/Azure/azure-storage-net-data-movement/issues/12
context.ShouldOverwriteCallback = (source, destination) =>
{
var sourceFile = new FileInfo((string)source);
var destBlob = destination as CloudBlob;
return sourceFile.LastWriteTimeUtc > destBlob.Properties.LastModified;
};
// Start the upload
var transferStatus = await TransferManager.UploadDirectoryAsync(sourceDirPath, destDir, options, context);
目前传输操作是由应用程序事件触发的。在短时间内试验了几个事件后,这引发了一个异常,如下所示。由于 TransferManager 是静态的 class,如何在我的应用程序中解决此要求并防止此类异常?
Microsoft.WindowsAzure.Storage.DataMovement.TransferException was unhandled
Message: An unhandled exception of type 'Microsoft.WindowsAzure.Storage.DataMovement.TransferException' occurred in mscorlib.dll
Additional information: A transfer operation with the same source and destination already exists.
您是否向 TransferManager 添加了超过 1 个具有相同 source/destination 的传输任务(例如,运行 以上代码在您的应用程序中多次添加)。如果是这样,您将遇到问题,因为 DMlib 不允许 运行 超过 1 个传输任务同时具有相同的 source/destination。
以下是运行上传10次的代码。请根据您的要求进行修改。
请注意,您需要等待之前的任务完成,然后添加一个具有相同源和目标以及新传输上下文的新传输任务。
for (int i = 0; i < 10; i++)
{
// Create Transfer Context
DirectoryTransferContext context = new DirectoryTransferContext();
//if dest blob exist just overwrite it
context.ShouldOverwriteCallback = TransferContext.ForceOverwrite;
// Start the upload and wait for it to finish
Task<TransferStatus> task = TransferManager.UploadDirectoryAsync(sourceDirPath, destDir, options, context);
task.Wait();
//Add some code to check the task.Result, following code only print the result
Console.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", task.Result.NumberOfFilesTransferred, task.Result.NumberOfFilesFailed, task.Result.NumberOfFilesSkipped, task.Result.BytesTransferred));
}
我觉得你的问题没有优化好。我觉得你遇到了和我一样的问题。让我简单解释一下。你是 运行 异步 DirectoryUpload,当然在这种情况下 "multiple transfer operations" 会。
在大多数情况下,如果跳过文件,则会发生此异常。这就是为什么您收到 "A transfer operation with the same source and destination already exists." 错误的原因。在这种情况下,进度将跳过图像,您必须如下捕获这些图像。查看完整示例 here
DirectoryTransferContext context = new DirectoryTransferContext();
context.FileTransferred += FileTransferredCallback;
context.FileFailed +=FileFailedCallback;
context.FileSkipped += FileSkippedCallback;
context.SetAttributesCallback = (destination) =>
{
CloudBlob destBlob = destination as CloudBlob;
destBlob.Properties.ContentType = "image/png";
};
context.ShouldTransferCallback = (source, destination) =>
{
// Can add more logic here to evaluate whether really need to transfer the target.
return true;
};
// Start the upload
var trasferStatus = await TransferManager.UploadDirectoryAsync(sourceDirPath, destDir, options, context);
private static void FileTransferredCallback(object sender, TransferEventArgs e)
{
Console.WriteLine("Transfer Succeeds. {0} -> {1}.", e.Source, e.Destination);
}
private static void FileFailedCallback(object sender, TransferEventArgs e)
{
Console.WriteLine("Transfer fails. {0} -> {1}. Error message:{2}", e.Source, e.Destination, e.Exception.Message);
}
private static void FileSkippedCallback(object sender, TransferEventArgs e)
{
Console.WriteLine("Transfer skips. {0} -> {1}.", e.Source, e.Destination);
}
示例中缺少的是如何处理覆盖现有图像(如果它们不相同)。
我不确定这是否在 0.3 版中可用,但我也是在安装 0.4.1 版 Microsoft.WindowsAzure.Storage.DataMovement 软件包后才发现的。下面的代码将比较源和目标并决定是否应该覆盖。
context.ShouldOverwriteCallback = (source, destination) =>
{
if(TransferContext.Equals(source, destination)==true)
return false;
else
return true;
};
我刚开始使用Azure Storage Data Movement Library (DML) having code similar to public DML sample code。用例是(增量地)将本地目录同步到 blob 存储多次,同时目录中的某些文件会不时更新。
UploadDirectoryOptions options = new UploadDirectoryOptions
{
SearchPattern = "*.*",
Recursive = false,
BlobType = BlobType.BlockBlob
};
// Register for transfer event.
DirectoryTransferContext context = new DirectoryTransferContext();
//only copy newer files - similar to AzCopy /XO /XN switches
//https://github.com/Azure/azure-storage-net-data-movement/issues/12
context.ShouldOverwriteCallback = (source, destination) =>
{
var sourceFile = new FileInfo((string)source);
var destBlob = destination as CloudBlob;
return sourceFile.LastWriteTimeUtc > destBlob.Properties.LastModified;
};
// Start the upload
var transferStatus = await TransferManager.UploadDirectoryAsync(sourceDirPath, destDir, options, context);
目前传输操作是由应用程序事件触发的。在短时间内试验了几个事件后,这引发了一个异常,如下所示。由于 TransferManager 是静态的 class,如何在我的应用程序中解决此要求并防止此类异常?
Microsoft.WindowsAzure.Storage.DataMovement.TransferException was unhandled
Message: An unhandled exception of type 'Microsoft.WindowsAzure.Storage.DataMovement.TransferException' occurred in mscorlib.dll
Additional information: A transfer operation with the same source and destination already exists.
您是否向 TransferManager 添加了超过 1 个具有相同 source/destination 的传输任务(例如,运行 以上代码在您的应用程序中多次添加)。如果是这样,您将遇到问题,因为 DMlib 不允许 运行 超过 1 个传输任务同时具有相同的 source/destination。
以下是运行上传10次的代码。请根据您的要求进行修改。 请注意,您需要等待之前的任务完成,然后添加一个具有相同源和目标以及新传输上下文的新传输任务。
for (int i = 0; i < 10; i++)
{
// Create Transfer Context
DirectoryTransferContext context = new DirectoryTransferContext();
//if dest blob exist just overwrite it
context.ShouldOverwriteCallback = TransferContext.ForceOverwrite;
// Start the upload and wait for it to finish
Task<TransferStatus> task = TransferManager.UploadDirectoryAsync(sourceDirPath, destDir, options, context);
task.Wait();
//Add some code to check the task.Result, following code only print the result
Console.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", task.Result.NumberOfFilesTransferred, task.Result.NumberOfFilesFailed, task.Result.NumberOfFilesSkipped, task.Result.BytesTransferred));
}
我觉得你的问题没有优化好。我觉得你遇到了和我一样的问题。让我简单解释一下。你是 运行 异步 DirectoryUpload,当然在这种情况下 "multiple transfer operations" 会。
在大多数情况下,如果跳过文件,则会发生此异常。这就是为什么您收到 "A transfer operation with the same source and destination already exists." 错误的原因。在这种情况下,进度将跳过图像,您必须如下捕获这些图像。查看完整示例 here
DirectoryTransferContext context = new DirectoryTransferContext();
context.FileTransferred += FileTransferredCallback;
context.FileFailed +=FileFailedCallback;
context.FileSkipped += FileSkippedCallback;
context.SetAttributesCallback = (destination) =>
{
CloudBlob destBlob = destination as CloudBlob;
destBlob.Properties.ContentType = "image/png";
};
context.ShouldTransferCallback = (source, destination) =>
{
// Can add more logic here to evaluate whether really need to transfer the target.
return true;
};
// Start the upload
var trasferStatus = await TransferManager.UploadDirectoryAsync(sourceDirPath, destDir, options, context);
private static void FileTransferredCallback(object sender, TransferEventArgs e)
{
Console.WriteLine("Transfer Succeeds. {0} -> {1}.", e.Source, e.Destination);
}
private static void FileFailedCallback(object sender, TransferEventArgs e)
{
Console.WriteLine("Transfer fails. {0} -> {1}. Error message:{2}", e.Source, e.Destination, e.Exception.Message);
}
private static void FileSkippedCallback(object sender, TransferEventArgs e)
{
Console.WriteLine("Transfer skips. {0} -> {1}.", e.Source, e.Destination);
}
示例中缺少的是如何处理覆盖现有图像(如果它们不相同)。
我不确定这是否在 0.3 版中可用,但我也是在安装 0.4.1 版 Microsoft.WindowsAzure.Storage.DataMovement 软件包后才发现的。下面的代码将比较源和目标并决定是否应该覆盖。
context.ShouldOverwriteCallback = (source, destination) =>
{
if(TransferContext.Equals(source, destination)==true)
return false;
else
return true;
};