从BackgroundWorker迁移到async/await方法

3

我一直在使用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();
                }
        }

现在,我想开始迁移到C# 5.0的Task(异步/等待)方式,因此我在这个例子中所做的是:

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个回答

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方法转换为异步方法? - VAAA
只需重新生成C#的包装器即可,点击这里获取详细步骤。 - avo
我所做的是右键点击服务并选择“配置服务引用...”,然后我勾选了“允许生成异步操作”的选项。然后重新编译,但我没有看到任何异步方法被添加。有什么线索吗? - VAAA
更正:生成基于任务的操作(第一个选项)。但这是默认设置,对吧?也许您应该删除引用并重新添加。 - avo
太好了!!成功了!!非常感谢 :) - VAAA
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接