首页 > 解决方案 > 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
        //}
    }

我想要实现的是:

到目前为止我想到的是

我很确定我的两个想法都不聪明,但现在我想不出一个聪明的方法来做到这一点。

标签: c#asynchronousmvvmasync-awaitmahapps.metro

解决方案


我终于找到了以更现代的方式工作的 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;
    }

推荐阅读