从backgroundworker迁移到async / await方法

时间:2013-08-17 15:44:24

标签: c# multithreading task-parallel-library backgroundworker async-await

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

但是在这里我得到一条消息说“这种异步方法缺乏'等待'运算符并将同步运行”。

有关最佳实践和正确方法的任何线索,以实现我想要完成的任务?

1 个答案:

答案 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