c# - C# MVVM,等待一些事件触发并继续更新 UI
问题描述
我正在构建一个 MMVMLight 应用程序,它在某些时候必须将文件上传到天蓝色存储帐户,然后在成功的情况下更新 SQL 服务器中的一些数据。
我的方法是这样工作的:
public ICommand UploadCICommand
{
get
{
if (_UploadCICommand == null)
{
_UploadCICommand = new RelayCommand(async () =>
{
try
{
ProgressDialogController controller;
// next upload CI
MetroDialogSettings dialogSettings = new MetroDialogSettings { AnimateHide = false, AnimateShow = true };
if ((await dialogCoordinator.ShowMessageAsync(this, "Confirm", $"Are you sure want to upload {appName} ?", MessageDialogStyle.AffirmativeAndNegative, (new MetroDialogSettings { AnimateHide = false, AnimateShow = true })) == MessageDialogResult.Affirmative))
{
controller = await dialogCoordinator.ShowProgressAsync(this, "Please Wait...", string.Empty, false, (new MetroDialogSettings { AnimateHide = false, AnimateShow = false }));
controller.SetMessage($"Uploading content");
CloudBlobContainer container = new CloudBlobContainer(new Uri(sasUri));
ICloudBlob blob = container.GetBlockBlobReference(zipFile);
BlobTransfer blobTransfer = new BlobTransfer();
blobTransfer.TransferCompleted += new AsyncCompletedEventHandler(blobTransfer_TransferCompleted);
blobTransfer.TransferProgressChanged += new EventHandler<BlobTransfer.BlobTransferProgressChangedEventArgs>(blobTransfer_TransferProgressChanged);
blobTransfer.UploadBlobAsync(blob, zipFile);
//And then, the code to update database....
}
}
}
}
}
}
void blobTransfer_TransferProgressChanged(object sender, BlobTransfer.BlobTransferProgressChangedEventArgs e)
{
var SetDebugBreakPointIfNeededHere = 1;
//Main stuff to do
// Parent object of sender -> controller.SetProgress(e.ProgressPercentage);
// Other information that would be cool to show
//Speed = (e.Speed / 1024 / 1024).ToString("N0");
//TimeRemaining = e.TimeRemaining.ToString();
//Progress = e.ProgressPercentage;
//SizeDowloaded = (e.BytesSent / 1024 / 1024).ToString("N0");
}
void blobTransfer_TransferCompleted(object sender, AsyncCompletedEventArgs e)
{
var SetDebugBreakPointIfNeededHere = 1;
//EndTime = System.DateTime.Now;
//if (e.Cancelled)
//{
// Log cancel and try preventing main function to continue
//}
//else if (e.Error != null)
//{
// Log failure and try preventing main function to continue
//}
//else
//{
// Speed = ((((BlobSize) / 1024 / 1024) / (EndTime - StartTime).TotalSeconds)).ToString("N0");
// Let the caller method continue
//}
}
我想要实现的是:
- 如果转到更新数据库部分,请等待触发 TransferCompleted 事件
- 当我等待上传结束时,通过调用“controller.SetProgress();”来更新进度条;在我的 TransferProgressChanged 中,但在这种方法中,我无权访问控制器对象。
到目前为止我想到的是
- 对于第 1 点:在 blobTransfer_TransferCompleted 方法中设置我的“数据库更新代码”,以确保在触发事件之前不会调用它
- 对于第二点:由于进度更改事件的发送者是我的 BlobTransfer 对象,我仍然不知道如何调用我的对话框的设置进度方法。我可能正在考虑使用反射来获取我的发件人的父对象并尝试在此处更新值。
我很确定我的两个想法都不聪明,但现在我想不出一个聪明的方法来做到这一点。
解决方案
我终于找到了以更现代的方式工作的 Microsoft Azure 存储数据移动库:
CloudBlobContainer container = new CloudBlobContainer(new Uri(sasUri));
CloudBlockBlob blob = container.GetBlockBlobReference(Path.GetFileName(zipFile));
// Setup the number of the concurrent operations
TransferManager.Configurations.ParallelOperations = 64;
// Setup the transfer context and track the upoload progress
SingleTransferContext context = new SingleTransferContext();
context.ProgressHandler = new Progress<TransferStatus>((progress) =>
{
int percentage = (int)Math.Round((double)((double)progress.BytesTransferred / (double)zipFileInfo.Length * 100));
//controller.SetProgress(percentage);
controller.SetMessage($"Uploading content {percentage}%");
});
context.ShouldOverwriteCallbackAsync = new ShouldOverwriteCallbackAsync(ShouldTransferCallback);
// Upload a local blob
await TransferManager.UploadAsync(
zipFile, blob, null, context, CancellationToken.None);
ShouldTransferCallback 总是返回 true,因为我每次都想覆盖 blob。
private async Task<bool> ShouldTransferCallback(object source, object dest)
{
return true;
}