为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
繁星coding 2023-06-25 13:52:48
在为我的项目实现导出 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);    }一般来说,整个逻辑按我的预期工作,但我无法同时复制任务和更新进度栏。提前致谢
查看完整描述

1 回答

?
翻阅古今

TA贡献1780条经验 获得超5个赞

问题在于从异步处理切换到同步处理。您甚至可以在代码中执行两次。


如果您从 async wait 开始,则需要在整个调用层次结构中绘制它。


1) 从点击处理程序开始。async void这应该是层次结构中的唯一方法。在这里等下一篇


private async void exportButton_Click(object sender, EventArgs e)

{

    await processAttachments(attachments, folderName, problemId);

}

2)使下一个调用的方法返回一个任务并使用,Show以便copyAttachments随后执行并可以等待


          return Task here

                |

                v

private async Task 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.Show();  // <= !

    await copyAttachments(attachments, folderName, problemId);

}

3) 使用返回的任务fs.WriteAsync并等待它。让该copy方法再次返回一个 Task 以将其向上传播:


private void copy(Attachment attachment, string folderName, string problemId)

{

    ...

    try

    {

        using (fs = new FileStream(Path.Combine(exportPath, attachment.Name), FileMode.Create))

        {

            awaitfs.WriteAsync(attachment.Data, 0, attachment.Data.Length, this.cts.Token);

            fs.Flush();

            fs.Close();

            this.exportPopUp.performProgressBarStep();

        }           

    }

    ...

4)等待复制方法(如果你想逐个复制附件):


private async Task copyAttachments(Attachments attachments, string folderName, string problemId)

{

    foreach (Attachment attachment in attachments.attachments)

    {            

        await copy(attachment, folderName, problemId));

    }

}

这应该会产生一个可行的解决方案,其中两个表单都将保持响应,并且您将看到进度条已填满。


查看完整回答
反对 回复 2023-06-25
  • 1 回答
  • 0 关注
  • 104 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信