隐藏

c# – 如何等待await / async方法完成

发布:2021/10/22 16:57:36作者:管理员 来源:本站 浏览次数:830

我有以下Async方法:

private async void ProcessSearch()

{

   // get catalogs on first search

   if (_invoiceTypes == null && _invoiceAccounts == null)

   {

       var confWcf = new Data.ConfigurationWCF();

       _invoiceTypes = await confWcf.GetInvoiceTypesAsync(MainForm.State.Entity);

       _invoiceAccounts = await confWcf.GetInvoiceAccountsAsync(MainForm.State.Entity);

       confWcf.Dispose();

   }


   var seekWcf = new DataSeekWCF();

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


   if (_ds != null)

   {

       SetupInvoiceGrid();

   }

}


在_invoiceTypes,_invoiceAccounts和_ds完成之前,我不想执行SetupInvoiceGrid.


任何线索?我做得对吗?我应该使用Task而不是等待吗?


我已经想出了这个代码似乎正在工作,看起来很好,但我不知道它是否正确:


private void btnSearch_Click(object sender, EventArgs e)

{

   lock (lockObj)

   {

       if (_isBusy)

           return;

       else

           _isBusy = true;

   }


   ShowPleaseWait(Translate("Searching data. Please wait..."));

       if (_invoiceTypes == null && _invoiceAccounts == null)

       {

           var t = GetCatalogs();

           t.ContinueWith(t2 =>

           {

               if (t.IsCompleted) ProcessSearch();

           });

       }

       else

       {

           ProcessSearch();

       }

}


private async Task GetCatalogs()

{

   // get catalogs on first search

   Data.ConfigurationWCF confWcf = new Data.ConfigurationWCF();

   var task1 = confWcf.GetInvoiceTypesAsync(1);

   var task2 = confWcf.GetInvoiceAccountsAsync(1);

   confWcf.Dispose();


   await Task.WhenAll(task1, task2);


   _invoiceTypes = task1.Result;

   _invoiceAccounts = task2.Result;


   if (_invoiceTypes != null)

   {

       cboInvoiceType.DataSource = _invoiceTypes.Tables["invoice_types"];

       cboInvoiceType.DisplayMember = "description";

       cboInvoiceType.ValueMember = "code";

   }


}


private async void ProcessSearch()

{

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


   if (_ds != null)

   {

       SetupInvoiceGrid();

   }

   HidePleaseWait();

}


最佳答案

我回答了关于如何处理ProcessSearchAsync本身 here的完成的原始(?)问题.


要并行运行任务(如评论中所述),这里修改了代码,因为invoiceTypes == null和_invoiceAccounts == null检查,它会变得有点复杂.注意下面实现检查的方式稍微改变了逻辑(之前只有当_invoiceTypes和_invoiceAccounts都为null时才会调用WCF – 如果只有其中一个为null,那么它是什么?):


private async Task ProcessSearchAsync()

{


   Data.ConfigurationWCF confWcf = new Data.ConfigurationWCF();

   Task</*typeof _invoiceTypes*/> t1;

   Task</*typeof _invoiceAccounts*/> t2;


   if (_invoiceTypes == null)

       t1 = confWcf.GetInvoiceTypesAsync(MainForm.State.Entity);

   else

   {

       var tsc1 = new TaskCompletionSource</*typeof _invoiceTypes*/>();

       t1 = tsc1.Task;

       tsc1.SetResult(_invoiceTypes);

   }


   if ( _invoiceAccounts == null )

       t2 = confWcf.GetInvoiceAccountsAsync(MainForm.State.Entity);

   else

   {

       var tsc2 = new TaskCompletionSource</*typeof _invoiceAccounts*/>();

       t2 = tsc2.Task;

       tsc2.SetResult(_invoiceAccounts);

   }



   DataSeekWCF seekWcf = new DataSeekWCF();

   Task</*typeof _ds*/> t3 = seekWcf.SearchInvoiceAdminAsync(new Guid(cboEmployer.Value.ToString()), new Guid(cboGroup.Value.ToString()), txtSearchInvoiceNumber.Text, chkSearchLike.Checked, txtSearchFolio.Text, Convert.ToInt32(txtYear.Value));


   await Task.WhenAll(new Task[] {t1, t2, t3});

   _invoiceTypes = t1.Result;

   _invoiceAccounts = t2.Result;

   ds = t3.Result;


   if (_ds != null)

   {

       SetupInvoiceGrid();

   }


   confWcf.Dispose();

   seekWcf.Dispose();

}