问题
I'm using a ProgressBar with binding to show the progress when receiving a file from a remote device.
<ProgressBar Width="500" Height="50" Value="{Binding ProgressFileReceive}"/>
ProgressFileReceive is a property (double) in my View Model which has the percentage completion. So to update the Progress Bar, I add to this number.
The problem is I have the file transfer method in a different async method, and so to access this property I must use the following code :
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
() =>
{
// do something on the UI thread
ProgressFileReceive = (double)i / fileSize * 100;
});
This works but makes the whole process extremely slow, since at each iteration (there are over a thousand loops since I read byte-by-byte) the method has to use the dispatcher to update the UI. It takes several times longer to receive the whole file, than it would take if I was not updating the UI.
How can I do this more efficiently so as to speed up the process ?
回答1:
The problem is I have the file transfer method in a different async method
That doesn't necessarily follow. You shouldn't need to use CoreDispatcher explicitly. Asynchronous methods resume on the UI thread by default.
For progress reporting, you should use IProgress<T>. You can use it with a structure to report progress, as such:
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
});
}
...
}
Then you can consume it with an IProgress<T> implementation. Since you need UI throttling, you can use 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);
}
来源:https://stackoverflow.com/questions/38247499/how-can-i-efficiently-update-the-ui-from-an-async-method