我刚开始使用代码类似于Azure Storage Data Movement Library (DML)的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是一个静态类,如何在我的应用程序中解决此要求并防止此类异常?
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.
答案 0 :(得分:1)
我认为你的问题没有得到很好的优化。我觉得你和我有同样的问题。让我简单解释一下。你正在运行异步DirectoryUpload,当然在这种情况下"多个传输操作"将会。
在大多数情况下,如果跳过文件,则会发生此异常。这就是为什么你得到一个错误"具有相同源和目的地的传输操作已经存在。"在这种情况下,进度将跳过图像,您必须捕获如下所示。请参阅完整示例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;
};
答案 1 :(得分:0)
您是否向TransferManager添加了多个具有相同源/目标的传输任务(例如,在您的应用程序中多次运行代码)。如果是这样,您将遇到问题,因为DMlib不允许同时运行具有相同源/目的地的多个传输任务。
答案 2 :(得分:0)
以下是运行上传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));
}