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();
                }
        }

现在,我想开始迁移到 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'运算符并且将同步运行”。

关于最佳实践和正确方法来完成我想要完成的事情的任何线索?

4

1 回答 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());
    }
}

编辑:注意,最初我忘记TaskScheduler在调用时指定ContinueWith。这可能导致在continuationAction池线程上被调用。

于 2013-08-17T15:53:58.117 回答