【发布时间】:2015-12-10 15:39:20
【问题描述】:
我过去曾在 Windows 窗体应用程序中使用过 BackgroundWorker。
对于我的新练习,我需要在 worker 内部使用 async 方法,对此我有点困惑。
这是我的代码结构。在表单加载事件中,我正在创建 BackgroundWorker 对象和设置事件
private void fMain_Load( object sender, EventArgs e ) {
bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork += new DoWorkEventHandler( bw_DoWork );
bw.ProgressChanged += new ProgressChangedEventHandler( bw_ProgressChanged );
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler( bw_RunWorkerCompleted );
}
当用户单击按钮时,我正在启动工作人员
private void btnGenerate_Click( object sender, EventArgs e ) {
Settings settings = new Settings();
pbCounter.Visible = true;
btnGenerate.Enabled = false;
bw.RunWorkerAsync( settings );
}
这是工作代码
private async void bw_DoWork( object sender, DoWorkEventArgs e ) {
try {
for ( int ix = 1; i <= 100; i++ ) {
using (var client = new HttpClient()) {
[???? how to call and wait here ????]
HttpResponseMessage response = await client.PostAsync( "endpoint", new StringContent( JsonConvert.SerializeObject( formContent ), Encoding.UTF8, "application/json" ) );
}
//The counter will keep track of your process
Application.DoEvents();
int percentage = ix * 100 / settings.TotalRuns;
bw.ReportProgress( percentage );
}
}
catch ( Exception ex ) {
MessageBox.Show( ex.Message, "Gift Creator", MessageBoxButtons.OK, MessageBoxIcon.Error );
}
}
【问题讨论】:
-
我不认为
BackgroundWorker与 async-await 配合得很好。您可能应该使用其他东西(或构建它)。 -
那行不通。如果您将
DoWork处理程序async并在内部使用await,则该方法将返回那里并且后台工作程序将完成。我认为您在使用异步时不需要后台工作人员,但必须考虑一下如何报告进度。 -
@RenéVogt:对。我想把后台工作人员扔掉。但是我非常喜欢它处理进度通知的方式。有什么建议吗?
-
您可以简单地将
for循环原样(包括await)放入您的按钮处理程序并从那里更新进度条(对于每次迭代)。我不知道HttpClient类以及它是否报告进度。但是您似乎只想显示 loop 的进度。
标签: c# async-await backgroundworker asp.net-4.5