从BackgroundWorker的迁移到异步/ await方法 [英] Migrate from backgroundworker to async / await methods
问题描述
我一直在使用一个WinForms C#应用程序BackgroundWorkers做任何WCF服务的数据呼叫象下面这样:
I have been using in a WinForms C# application BackgroundWorkers to do any WCF service data calls like below:
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;
}
}
为了调用后台工作为我做例子:
In order to call the background worker I do for example:
private void btnSearch_Click(object sender, EventArgs e)
{
if (!_worker.IsBusy)
{
ShowPleaseWait(Translate("Searching data. Please wait..."));
_workerType = "search";
_worker.RunWorkerAsync();
}
}
现在,我想开始迁移至任务(异步/等待)C#5.0,所以我在这个例子中所做的是:
Now, I would like to start migrating to Task (async / await) C# 5.0, so what I did in this example was:
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();
}
但在这里我得到一个消息,说此异步方法缺乏'等待'经营者和将同步运行。
But here I get a message saying that "this async method lacks 'await' operators and will run synchronously".
如何是最好的做法,这样做我想要完成什么?正道任何线索
Any clue on how is the best practice and the right way to do what I want to accomplish?
推荐答案
在理想情况下,你的WCF服务包装应该有它的方法异步版本,即 SearchInvoiceAdminAsync
。然后你会指日可待:
Ideally, your WCF service wrapper should have Async versions of its methods, i.e. SearchInvoiceAdminAsync
. Then you'd await for it:
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: A different matter is that eventually you'd need to call your async method from a regular method, e.g, upon a button click, and perhaps do something when the task is done. Here is a very simplistic scenario:
// 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
被称为一个线程池
EDITED: Note, initially I forgot to specify TaskScheduler
when calling ContinueWith
. That might have resulted in continuationAction
being called on a pool thread.
这篇关于从BackgroundWorker的迁移到异步/ await方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!