将后台工作程序更新为异步等待

2023-11-27

这就是我目前使用后台工作程序将大量内容保存到文件的方式,同时向用户呈现进度条并防止在保存过程中对 UI 进行任何更改。我想我已经抓住了基本特征。模态ProgressWindow显示进度条,仅此而已。我该如何将其更改为async-await模式,如果我必须的话?

private ProgressForm ProgressWindow { get; set; }

/// <summary>On clicking save button, save stuff to file</summary>
void SaveButtonClick(object sender, EventArgs e)
{
  if (SaveFileDialog.ShowDialog() == DialogResult.OK)
  {
    if (!BackgroundWorker.IsBusy)
    {
      BackgroundWorker.RunWorkerAsync(SaveFileDialog.FileName);
      ProgressWindow= new ProgressForm();
      ProgressWindow.SetPercentageDone(0);
      ProgressWindow.ShowDialog(this);
    }
  }
}

/// <summary>Background worker task to save stuff to file</summary>
void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
  string path= e.Argument as string;

  // open file

  for (int i=0; i < 100; i++)
  {
    // get some stuff from UI
    // save stuff to file
    BackgroundWorker.ReportProgress(i);
  }

  // close file
}

/// <summary>On background worker progress, report progress</summary>
void BackgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
{
  ProgressWindow.SetPercentageDone(e.ProgressPercentage);
}

/// <summary>On background worker finished, close progress form</summary>
void BackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  ProgressWindow.Close();
}

我有一个博客系列详细介绍了这一点。

简而言之,BackgroundWorker被替换为Task.Run, and ReportProgress(和朋友)被替换为IProgress<T>.

所以,一个简单的翻译应该是这样的:

async void SaveButtonClick(object sender, EventArgs e)
{
  if (SaveFileDialog.ShowDialog() == DialogResult.OK)
  {
    ProgressWindow = new ProgressForm();
    ProgressWindow.SetPercentageDone(0);
    var progress = new Progress<int>(ProgressWindow.SetPercentageDone);
    var task = SaveAndClose(SaveFileDialog.FileName, progress));
    ProgressWindow.ShowDialog(this);
    await task;
  }
}

async Task SaveAndClose(string path, IProgress<int> progress)
{
  await Task.Run(() => Save(path, progress));
  ProgressWindow.Close();
}

void Save(string path, IProgress<int> progress)
{
  // open file

  for (int i=0; i < 100; i++)
  {
    // get some stuff from UI
    // save stuff to file
    if (progress != null)
      progress.Report(i);
  }

  // close file
}

改进注意事项:

  • 让后台线程访问 UI 通常不是一个好主意(// get some stuff from UI)。如果您可以从 UI 收集所有信息,效果可能会更好before呼叫Task.Run然后将其传递到Save method.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将后台工作程序更新为异步等待 的相关文章

随机推荐

  • Send() 之后的 UdpClient、Receive() 不起作用?

    考虑以下代码 client Send data data Length endpoint byte response client Receive ref endpoint 然而 根据 WireShark 网络嗅探器 的说法 远程主机确实会
  • 键盘显示元素的位置混乱

    我有需要手机触摸键盘输入的游戏 它的显示有问题 每当键盘出现在文本输入焦点时 我的所有位置 绝对的元素都会变得混乱 是否有一个插件可以使移动键盘始终显示 以便我重新定位所有元素 或者我需要更改 css 来制作元素 以便键盘显示时不会混乱 我
  • 直接连接到 SQL Azure 时的登录前握手问题

    目前 我们的开发环境中遇到了一个相当麻烦的问题 并显示以下消息 A connection was successfully established with the server but then an error occurred dur
  • 使用 java 处理 Postgresql 事务

    我有两个带有preparedStatement 的查询块 这是第一个 String sql update cikan malzeme set miktar where proje id and malzeme id PreparedStat
  • 支持转储和加载的纯 Javascript YAML 库? [复制]

    这个问题在这里已经有答案了 这样的事情存在吗YAML aka YAML 如果这个曾经存在过 那么它一定已经被抹去了 因为最新的搜索结果一无所获 看起来有很多实现dump仅从 Javascript 到 YAML 输出 但很难找到支持转储和加载
  • serviceAccountKey 在哪里或者是什么。json 是 firebase 实时数据库的 Node js 示例

    我已经下载了 zipFirebase real time database node js sample并导航到数据库部分 https github com firebase quickstart nodejs tree master da
  • 如何从 URL 字符串中获取参数?

    我有一个 HTML 表单字段 POST url 有一些 URL 字符串作为值 示例值是 https example com test email protected https example com test email protecte
  • 在原始返回类型函数上返回“null”?

    我有一个函数返回一个int给定键的值 来自HashMap
  • 查找nohup命令运行的进程

    我使用以下命令在 Centos 中运行服务器可执行文件 nohup server 现在我需要终止该进程 server 但我尝试过 ps a 命令来获取PID但我无法获得该过程 知道如何杀死 server now ps auxwww grep
  • “R 无法解析为变量”? [复制]

    这个问题在这里已经有答案了 在 Eclipse 中 我从源创建了一个项目 现在它显示错误 R 无法解析为变量 从我在这里发现的情况来看 我已经清除并重建了项目 但 R 文件仍然没有出现在 gen 文件夹中 有任何想法吗 不用担心 首先 您可
  • Pandas - 按连续范围分组

    我有一个具有以下结构的数据框 开始 结束和高度 数据框的一些属性 数据帧中的一行始终从上一行结束的位置开始 即如果第 n 行的结尾是 100 则第 n 1 行的开头是 101 第 n 1 行的高度始终与第 n 1 行的高度不同 这就是数据位
  • Ruby File.open 模式和选项是什么?

    Ruby s File open将模式和选项作为参数 在哪里可以找到模式和选项的完整列表 In Ruby IO 模块文档 我想 Mode Meaning r Read only starts at beginning of file def
  • CSS 定位 - 两个相邻的元素

    好吧 我知道这个问题已经出现了至少数百次 但这个定位让我发疯 有人可以帮助我吗 我有一个带有表格和 div 标签的 portlet 页面 基本上是 html 我想将它们放置在彼此旁边 表格在左侧 div 在右侧 以下是我的 html 的部分
  • 如何将文本文件与我的类库一起包含在 Visual Studio 2017 为我创建的 NuGet 包中?

    我的文本文件位于我的类库项目中 我将其 构建操作 设置为 内容 并将 复制到输出目录 设置为 如果较新则复制 因此 csproj 有一个类似以下的部分
  • 更改另一个 PFuser 对象中的数据

    在我的游戏中 一个用户可以对另一个用户造成伤害 并拿走他们的一些金币 gold 变量存储在其他用户的 PFUser 对象中 一个用户如何更改存储在其他用户 PFUser 对象中的黄金值 您无法保存或删除未经身份验证的 PFUser 实现该功
  • 延续 monad 中的 StackOverflow

    使用以下延续单子 type ContinuationMonad member this Bind m f fun c gt m fun a gt f a c member this Return x fun k gt k x let con
  • C++ 为可变参数重载运算符逗号

    是否可以通过重载参数的运算符逗号来构造函数的可变参数 我想看一个例子如何做到这一点 也许是这样的 template
  • 了解何时以及如何使用 Java 8 Lambda

    我花了一些时间尝试学习 Java 8 的一些新功能 作为练习 我使用一些 Java 8 函数接口编写了一个 MergeSort 我在下面包含了完整的代码 可能存在错误 优化 我只对与 Java 8 功能相关的它们感兴趣 我的问题是 我相信当
  • 获取2点之间的所有像素坐标

    我想获取 2 个给定点之间直线上的所有 x y 坐标 虽然这看起来是一项很容易的任务 但我似乎无法理解它 因此 例如 点 1 10 5 点 2 15 90 Edit 下面的解决方案仅适用于几何角度 在屏幕上绘图与理论几何不同 您应该听取人们
  • 将后台工作程序更新为异步等待

    这就是我目前使用后台工作程序将大量内容保存到文件的方式 同时向用户呈现进度条并防止在保存过程中对 UI 进行任何更改 我想我已经抓住了基本特征 模态ProgressWindow显示进度条 仅此而已 我该如何将其更改为async await模