将后台工作程序更新为async-await

Gra*_*ham 8 c# backgroundworker winforms async-await

因此,这就是我目前使用后台工作程序将大量内容保存到文件中的方式,同时向用户显示进度条并防止在保存过程中对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();
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*ary 11

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

简而言之,BackgroundWorker被替换为Task.Run,和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
}
Run Code Online (Sandbox Code Playgroud)

改进注意事项:

  • 让后台线程进入UI(// get some stuff from UI)并不是一个好主意.如果您可以调用之前从UI收集所有信息Task.Run并将其传递给Save方法,那么它可能会更好.