从 backgroundworker 迁移到 async / await 方法
Posted
技术标签:
【中文标题】从 backgroundworker 迁移到 async / await 方法【英文标题】:Migrate from backgroundworker to async / await methods 【发布时间】:2013-08-17 15:44:24 【问题描述】:我一直在 WinForms C# 应用程序 BackgroundWorkers 中使用如下所示的任何 WCF 服务数据调用:
private void Worker_DoWork(object sender, DoWorkEventArgs e)
switch (_workerType)
case "search":
Data.SeekWCF seekWcf = new Data.SeekWCF();
_ds = seekWcf.SearchInvoiceAdmin(new Guid(cboEmployer.Value.ToString()), new Guid(cboGroup.Value.ToString()), txtSearchInvoiceNumber.Text, chkSearchLike.Checked, txtSearchFolio.Text, Convert.ToInt32(txtYear.Value));
seekWcf.Dispose();
break;
case "update":
Data.AccountingWCF accWcf = new Data.AccountingWCF();
_returnVal = accWcf.UpdateInvoiceAdmin(_ds);
accWcf.Dispose();
break;
例如,为了调用后台工作人员:
private void btnSearch_Click(object sender, EventArgs e)
if (!_worker.IsBusy)
ShowPleaseWait(Translate("Searching data. Please wait..."));
_workerType = "search";
_worker.RunWorkerAsync();
现在,我想开始迁移到 Task (async / await) C# 5.0,所以我在这个示例中所做的是:
private async void ProcessSearch()
Data.SeekWCF seekWcf = new Data.SeekWCF();
_ds = seekWcf.SearchInvoiceAdmin(new Guid(cboEmployer.Value.ToString()), new Guid(cboGroup.Value.ToString()), txtSearchInvoiceNumber.Text, chkSearchLike.Checked, txtSearchFolio.Text, Convert.ToInt32(txtYear.Value));
seekWcf.Dispose();
但是在这里我收到一条消息说“这个异步方法缺少'await'运算符并且将同步运行”。
任何关于最佳实践和正确方法来完成我想要完成的事情的线索?
【问题讨论】:
【参考方案1】:理想情况下,您的 WCF 服务包装器应具有其方法的异步版本,即 SearchInvoiceAdminAsync
。然后你会等待它:
private async Task ProcessSearchAsync()
Data.SeekWCF seekWcf = new Data.SeekWCF();
_ds = await seekWcf.SearchInvoiceAdminAsync(new Guid(cboEmployer.Value.ToString()), new Guid(cboGroup.Value.ToString()), txtSearchInvoiceNumber.Text, chkSearchLike.Checked, txtSearchFolio.Text, Convert.ToInt32(txtYear.Value));
seekWcf.Dispose();
已编辑:不同的是,最终您需要从常规方法调用异步方法,例如,在单击按钮时,并且可能在任务完成时执行某些操作。这是一个非常简单的场景:
// UI Thread
Task _pendingTask = null;
void button_click()
if ( _pendingTask != null)
MessageBox.Show("Still working!");
else
_pendingTask = ProcessSearchAsync();
_pendingTask.ContinueWith((t) =>
MessageBox.Show("Task is done!");
// check _pendingTask.IsFaulted here
_pendingTask = null;
, TaskScheduler.FromCurrentSynchronizationContext());
已编辑:注意,最初我在调用ContinueWith
时忘记指定TaskScheduler
。这可能会导致在池线程上调用 continuationAction
。
【讨论】:
如何将我的 WCF 方法转换为异步方法? 只需为其重新生成 C# 包装器,这里是 how。 我所做的是右键单击服务和“配置服务引用...”,然后我检查选项“允许生成异步操作”.. 并再次编译它,我没有看到添加了任何异步方法..任何线索=? 在“允许生成异步操作”下面还有两个单选按钮,“生成基于任务的操作”和“生成异步操作”。选择后者。 更正:“生成基于任务的操作”(第一个选项)。但那是你默认的,对吧?也许您应该删除引用并重新添加它。以上是关于从 backgroundworker 迁移到 async / await 方法的主要内容,如果未能解决你的问题,请参考以下文章
从 JBoss AS 7.1 迁移到 JBoss EAP 7.3.0
是不是 .NET 4.0 TPL 让 APM、EAP 和 BackgroundWorker 异步模式过时了?
EJB 远程客户端从 JBoss AS 7.1 迁移到 Wildfly 8.1