如何在执行异步操作时控制进度条

在为我的项目实现导出 util 的过程中,我遇到了上传文件期间阻止 UI 的问题。基本上问题是在异步任务期间我无法更新进度栏。


我已经尝试了几种解决方案。一般来说,当我调用exportPopUp.ShowDialog()时,它会阻止copyAttachment()的执行,并且整个逻辑在关闭表单后完成。我决定使用 Show() 但当我这样做时,表单不存在(全灰色)


这是我的背景逻辑:


   private void exportButton_Click(object sender, EventArgs e)

    {

        // get files

        int row = reportsDataGrid.CurrentCell.RowIndex;

        if (row >= 0)

        {

            string problemId = reportsDataGrid.Rows[row].Cells[0].Value.ToString();

            AC.Trace.I("Problem Id", problemId);

            FolderBrowserDialog dlgFolderBrowser = new FolderBrowserDialog();

            dlgFolderBrowser.Description = "Select folder to save Report files!";

            DialogResult result = dlgFolderBrowser.ShowDialog();

            if (result == DialogResult.OK)

            {

                string folderName = dlgFolderBrowser.SelectedPath;

                AC.Trace.I("Destination folder name", folderName);

                CIS.PRS.Data.Attachments attachments = jampPrsService.ReportFiles(problemId);

                processAttachments(attachments, folderName, problemId);

            }

        }

    }


    private async void processAttachments(Attachments attachments, string folderName, string problemId)

    {

        this.exportPath = folderName + "\\" + problemId;

        cts = new CancellationTokenSource();

        this.exportPopUp = new exportPopUp(attachments.Size(), cts);

        this.exportPopUp.ExportFinished += ExportPopUp_ExportFinished;

        exportPopUp.setExportLabelText("Exporting problem report " + problemId);

        exportPopUp.ShowDialog();

        await copyAttachments(attachments, folderName, problemId);

    }

一般来说,整个逻辑按我的预期工作,但我无法同时复制任务和更新进度栏。提前致谢


繁星coding
浏览 105回答 1
1回答

翻阅古今

问题在于从异步处理切换到同步处理。您甚至可以在代码中执行两次。如果您从 async wait 开始,则需要在整个调用层次结构中绘制它。1) 从点击处理程序开始。async void这应该是层次结构中的唯一方法。在这里等下一篇private async void exportButton_Click(object sender, EventArgs e){&nbsp; &nbsp; await processAttachments(attachments, folderName, problemId);}2)使下一个调用的方法返回一个任务并使用,Show以便copyAttachments随后执行并可以等待&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Task here&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vprivate async Task processAttachments(Attachments attachments, string folderName, string problemId){&nbsp; &nbsp; this.exportPath = folderName + "\\" + problemId;&nbsp; &nbsp; cts = new CancellationTokenSource();&nbsp; &nbsp; this.exportPopUp = new exportPopUp(attachments.Size(), cts);&nbsp; &nbsp; this.exportPopUp.ExportFinished += ExportPopUp_ExportFinished;&nbsp; &nbsp; exportPopUp.setExportLabelText("Exporting problem report " + problemId);&nbsp; &nbsp; exportPopUp.Show();&nbsp; // <= !&nbsp; &nbsp; await copyAttachments(attachments, folderName, problemId);}3) 使用返回的任务fs.WriteAsync并等待它。让该copy方法再次返回一个 Task 以将其向上传播:private void copy(Attachment attachment, string folderName, string problemId){&nbsp; &nbsp; ...&nbsp; &nbsp; try&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; using (fs = new FileStream(Path.Combine(exportPath, attachment.Name), FileMode.Create))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; awaitfs.WriteAsync(attachment.Data, 0, attachment.Data.Length, this.cts.Token);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fs.Flush();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fs.Close();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.exportPopUp.performProgressBarStep();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; ...4)等待复制方法(如果你想逐个复制附件):private async Task copyAttachments(Attachments attachments, string folderName, string problemId){&nbsp; &nbsp; foreach (Attachment attachment in attachments.attachments)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; await copy(attachment, folderName, problemId));&nbsp; &nbsp; }}这应该会产生一个可行的解决方案,其中两个表单都将保持响应,并且您将看到进度条已填满。
打开App,查看更多内容
随时随地看视频慕课网APP