我一直在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();
}
但是在这里我得到一条消息说“这种异步方法缺乏'等待'运算符并将同步运行”。
有关最佳实践和正确方法的任何线索,以实现我想要完成的任务?
答案 0 :(得分:1)
理想情况下,您的WCF服务包装器应该具有其方法的Async版本,即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());
}
}
已编辑:注意,最初我在调用TaskScheduler
时忘记指定ContinueWith
。这可能导致在池线程上调用continuationAction
。