[英]Progress tracking doesn't work in an UWP async method
我正在嘗試跟蹤我的 UWP 應用程序的導出進度。 它應該在我看來觸發一個進度環。 似乎正在發生的是導出邏輯占用同一個線程,並且在完成所有導出之后,就調用了我的 WorkInProgress 的設置器。
我的觀點:
<ProgressRing x:Name="LibraryProgressRing"
Style="{StaticResource ProgressRingBase}"
IsActive="{x:Bind ViewModel.WorkInProgress, Mode=OneWay}" />
我的 ViewModel 方法:
private async void ExportItems(ExportType type)
{
var progress = new Progress<bool>();
progress.ProgressChanged += (sender, workInProgress) => WorkInProgress = workInProgress;
var model = SelectedNote.Model;
await _exportService.ExportSingleAsync(model, type, progress);
}
我的導出方法:
public async Task ExportSingleAsync(MyModel model, ExportType exportType, IProgress<bool> progress)
{
var dto = new ModelDto()
{
Id = model.Id,
Ink = await _storageService.GetInkModel(model.Id),
Language = model.LanguageName,
Title = model.Title
};
var savePicker = new FileSavePicker();
savePicker.FileTypeChoices.Add($"{exportType.GetFileType()}", new List<string> { exportType.GetFileExtension() });
savePicker.SuggestedFileName = dto.Title;
var file = await savePicker.PickSaveFileAsync();
if (file != null)
{
progress.Report(true);
switch (exportType)
{
case ExportType.Txt:
var fileFormat = exportType.GetFileFormat();
var txt = await CreateTextFromApi(dto, fileFormat);
await FileIO.WriteBytesAsync(file, txt);
break;
case ExportType.Jpg:
case ExportType.Png:
var image = CreateLocalImage(dto);
await _storageService.StoreBitmapAsync(file, image);
break;
case ExportType.Svg:
var svg = await CreateImageFromApi(dto, exportType);
await FileIO.WriteBytesAsync(file, svg);
break;
case ExportType.Pdf:
var pdf = await CreatePdfFromApi("vector", dto);
await FileIO.WriteBytesAsync(file, pdf);
break;
case ExportType.Doc:
var doc = await CreateDocFromApi(dto);
await FileIO.WriteBytesAsync(file, doc);
break;
default:
throw new NotImplementedException($"Single item export is not supported with {exportType.GetFileFormat()} file format.");
}
progress.Report(false);
}
}
請告訴我我的假設是否正確,這是一個阻塞的線程問題以及可能導致它的原因。 它確實成功觸發了第二部分的 ProgressRing,因此它肯定不是 xaml/綁定問題。 我需要在 progress.Report(true) 被觸發后立即調用我的 WorkInProgress 設置器。
提前致謝!
我發現了根本問題—— CreateImageFromApi 方法內部的一個邏輯依賴於 UIThread,因此整個方法在那里同步執行。 我們必須更改底層邏輯,並編寫以下代碼以獲得良好的衡量標准:
public async Task ExportSingleAsync(MyModel model, ExportType exportType, IProgress<bool> progress)
{
var dto = new ModelDto()
{
Id = model.Id,
Ink = await _storageService.GetInkModel(model.Id),
Language = model.LanguageName,
Title = model.Title
};
var savePicker = new FileSavePicker();
savePicker.FileTypeChoices.Add($"{exportType.GetFileType()}", new List<string> { exportType.GetFileExtension() });
savePicker.SuggestedFileName = dto.Title;
var file = await savePicker.PickSaveFileAsync();
if (file != null)
{
progress.Report(true);
await Task.Run(() => ExportFilesAsync(exportType, notes, folder));
progress.Report(false);
}
}
該開關位於 ExportFilesAsync 方法內。 Task.Run 強制方法在新線程中執行。 這釋放了 UIThread 來處理 ProgressChanged 回調。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.