其他分享
首页 > 其他分享> > 我如何才能有效地从异步方法更新UI?

我如何才能有效地从异步方法更新UI?

作者:互联网

我正在使用带有绑定的ProgressBar来显示从远程设备接收文件时的进度.

<ProgressBar Width="500" Height="50" Value="{Binding ProgressFileReceive}"/>

ProgressFileReceive是视图模型中的属性(双精度),具有完成百分比.因此,要更新进度栏,请添加此编号.

问题是我在另一个异步方法中有文件传输方法,因此要访问此属性,我必须使用以下代码:

await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
   () =>
   {
       // do something on the UI thread
       ProgressFileReceive = (double)i / fileSize * 100;
   });

这行得通,但会使整个过程变得极其缓慢,因为在每次迭代中(自从逐字节读取以来,都有超过一千个循环),该方法必须使用分派器来更新UI.接收整个文件所花的时间要比不更新UI所花费的时间长几倍.

我如何才能更有效地做到这一点,以加快流程?

解决方法:

The problem is I have the file transfer method in a different async method

这并不一定要遵循.您不需要显式使用CoreDispatcher.默认情况下,异步方法在UI线程上恢复.

对于进度报告,您应该使用IProgress< T>.您可以将其与报告进度的结构一起使用,例如:

public struct ProgressReport
{
  public double Progress { get; set; }
  public double FileSize { get; set; }
}

async Task FileTransferAsync(IProgress<ProgressReport> progress)
{
  ...
  if (progress != null)
  {
    progress.Report(new ProgressReport
    {
      Progress = (double)i,
      FileSize = fileSize
    });
  }
  ...
}

然后,您可以使用IProgress< T>实施.由于需要UI限制,因此可以使用one that I wrote that has built-in throttling

using (var progress = ObservableProgress<ProgressReport>.CreateForUi(value =>
    {
        ProgressFileReceive = (double)value.Progress / value.FileSize * 100;
    }))
{
    await FileTransferAsync(progress);
}

标签:windows-runtime,windows-store-apps,mvvm-light,winrt-async,c
来源: https://codeday.me/bug/20191118/2028187.html