大家好,
我遇到了一个小问题。我有一个WPF应用程序,它读取一个相当大的Excel文件,然后将其输出为XML文件。我面临的问题是,我想将操作的进度报告回处理程序。
我无法使其“平滑”运行,也就是说,GUI线程中的进度条一次性被填充,然后紧接着从Excel文件中读取的内容被填充到DataGrid中。
我对Async/Await/Task很陌生,以前一直在使用BackgroundWorker,但我希望更多地了解这方面的知识,所以如果这是一个愚蠢的问题,我很抱歉。
我已经阅读了Stephen Cleary的教程,链接在这里。
老实说,我不知道为什么进度条不能像应该一样“平滑”填充...
在GUI中调用的代码:
var progress = new Progress<int>(progressPercent => pBar.Value = progressPercent);
Task.Run(() => _sourceService.ReadFileContent(filePath, progress)).ContinueWith(task =>
{
dataGrid.ItemsSource = task.Result.DefaultView;
DataTable = task.Result;
if (DataTable.Rows.Count > 0)
BtnCreateXmlFile.IsEnabled = true;
}, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
ReadFileContent(filePath, progress)
的方法体如下:public DataTable ReadFileContent(string filePath, IProgress<int> progress)
{
var rowStart = 7;
var columnStart = 1;
var existingFile = new FileInfo(filePath);
using (var package = new ExcelPackage(existingFile))
{
var worksheet = package.Workbook.Worksheets["BOP"];
var dt = new DataTable();
// Compose the name of the table from:
// - Product Type
// - Customer
// - Customer Project
// * These can be found in the "CollaborationContext" sheet that is present in the ExcelFile.
if (package.Workbook.Worksheets["CollaborationContext"].SelectedRange["B6"].Value.Equals("object_type"))
{
dt.TableName = package.Workbook.Worksheets["CollaborationContext"].SelectedRange["C9"].Value + " " +
package.Workbook.Worksheets["CollaborationContext"].SelectedRange["D9"].Value + " " +
package.Workbook.Worksheets["CollaborationContext"].SelectedRange["E9"].Value;
}
dt.TableName = package.Workbook.Worksheets["CollaborationContext"].SelectedRange["B9"].Value + " " +
package.Workbook.Worksheets["CollaborationContext"].SelectedRange["C9"].Value + " " +
package.Workbook.Worksheets["CollaborationContext"].SelectedRange["D9"].Value;
// Report only in chunks. We do not want to call `progress.Report` for each row that is read.
var totalRows = worksheet.Dimension.End.Row;
var currentIndex = 0;
var percentageProgress = totalRows / 10;
// Get Columns and add them to the DataTable
for (var col = columnStart; col <= worksheet.Dimension.End.Column - 1; col++)
dt.Columns.Add(worksheet.Cells[6, col].Value.ToString());
// Place data into DataTable
for (var row = rowStart; row <= worksheet.Dimension.End.Row; row++)
{
var dr = dt.NewRow();
var x = 0;
currentIndex++;
for (var col = columnStart; col <= worksheet.Dimension.End.Column - 1; col++)
{
dr[x++] = worksheet.Cells[row, col].Value;
}
dt.Rows.Add(dr);
// Report progress back to the handler
if (currentIndex % percentageProgress == 0)
progress?.Report(row);
}
return dt;
}
}
感谢您提前的帮助!
progress?.Report()
中报告的数字。或者类似于这样的东西。我真的不理解if (currentIndex % percentageProgress == 0)
,但也许我只需要更仔细地阅读。 - adv12await
Task.Run()
pBar.Value = progressPercent
委托没有在UI线程上执行,因此不会更新。progress?.Report(row);
上设置了断点 - 它显示:未标记 > 2644 12 工作线程 TeamCenterExport.exe!TeamCenterExport.Service.ExcelSourceService.ReadFileContent 正常
。 - darksleepasync
标记ReadFileContent(string filePath, IProgress<int> progress)
并返回一个Task<DataTable>
,然后从GUI线程调用它,如var test = await _sourceService.ReadFileContent(filePath, progress)
,但是没有成功。 :( - darksleep