3

以下のような WCF サービス データ呼び出しを行うために、WinForms C# アプリケーション BackgroundWorkers で使用しています。

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

EDITED:別の問題は、最終的には、ボタンのクリック時など、通常のメソッドから非同期メソッドを呼び出す必要があり、おそらくタスクが完了したときに何かをする必要があるということです。以下は非常に単純化されたシナリオです。

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

EDITED:TaskScheduler注、最初は呼び出すときに指定するのを忘れていましたContinueWith。その結果continuationAction、プール スレッドで呼び出された可能性があります。

于 2013-08-17T15:53:58.117 に答える