簡體   English   中英

報告Async Task的進度

[英]Reporting progress from Async Task

你好開發者,

我面臨着一個輕微的困境。 我有一個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)的方法體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;
        } 

    }

先感謝您 !

首先,讓我們擺脫危險的ContinueWith調用。 你真的應該使用await

var progress = new Progress<int>(progressPercent => pBar.Value = progressPercent);
var result = await Task.Run(() => _sourceService.ReadFileContent(filePath, progress));
dataGrid.ItemsSource = result.DefaultView;
DataTable = result;
if (DataTable.Rows.Count > 0)
  BtnCreateXmlFile.IsEnabled = true;

接下來,您可能會看到進度的問題是您的Progress<int>處理程序期望progressPercent ,但ReadFileContent正在發送它讀取的行數, 而不是百分比。 所以,要解決這個問題:

if (currentIndex % percentageProgress == 0)
  progress?.Report(row * 100 / totalRows);

(此處還有其他幾個選項;例如,如果您想要更高級的用戶界面,您可以決定報告當前行總行數)。

進度條不能“順利”填充

我上面描述的是最低可接受的解決方案。 特別是,“僅更新10次”代碼有點問題; 無論更新的速度有多快或多慢,它總是會更新10次。 更通用的解決方案是使用基於Rx的IProgress解決方案,它允許您根據時間進行限制(例如,每秒4次更新)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM