这就是我目前使用后台工作程序将大量内容保存到文件的方式,同时向用户呈现进度条并防止在保存过程中对 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(使用前将#替换为@)