【问题标题】:Migrate from backgroundworker to async / await methods从 backgroundworker 迁移到 async / await 方法
【发布时间】: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'运算符并且将同步运行”。

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

【问题讨论】:

    标签: c# multithreading task-parallel-library backgroundworker async-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
    • 我所做的是右键单击服务和“配置服务引用...”,然后我检查选项“允许生成异步操作”.. 并再次编译它,我没有看到添加了任何异步方法..任何线索=?
    • 在“允许生成异步操作”下面还有两个单选按钮,“生成基于任务的操作”和“生成异步操作”。选择后者。
    • 更正:“生成基于任务的操作”(第一个选项)。但那是你默认的,对吧?也许您应该删除引用并重新添加它。
    猜你喜欢
    • 1970-01-01
    • 2018-09-20
    • 1970-01-01
    • 2014-11-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多