[英]Asynchronous call in synchronous method
這是一個簡單的例子:
public event EventHandler CookinDone = delegate{};
public void CoockinRequest(){
var indicator = new ActivityIndicator();
ActivityIndicator.Show("Oooo coockin' something cool");
var bw = new BackgroundWorker();
bw.DoWork += (sender, e) => CockinService.Cook();
bw.RunWorkerCompleted += (sender, e) => {
indicator.Hide();
CookinDone.Invoke(this,null);
};
bw.RunWorkerAsync();
}
現在,每次我使用該方法時,我都必須攔截CookinDone事件並繼續前進。
var cook = new Cook();
cook.CookinDone += (sender, e) => MessageBox.Show("Yay, smells good");
cook.CoockinRequest();
但是如何通過將方法的返回類型設置為布爾值並在Cookin完成時返回結果來簡化它?
if (CoockinRequest()) MessageBox.Show('Yay, smells even better');
如果我把那些東西放在那里while (bw.IsBusy)
它將擰緊我的ActivityIndicator,凍結主線程,我覺得這將是最糟糕的事情。 還有一些Monitor.Wait
東西和其他一些東西,如TaskFactory
,但所有這些東西似乎太復雜,無法在簡單的場景中使用。
它可能在不同的環境中也有所不同,例如某些方法對WPF應用程序有用,有些對於其他東西以及諸如此類的東西,但應該有一般模式不對嗎?
你是怎么做那些家伙的?
在.NET 4中沒有直接的方法可以做到這一點。這實際上非常符合下一版C#中新的async / await功能。
可以在.NET 4中使用任務並行庫來實現此目的。 您可以通過更改代碼以返回Task<bool>
來執行此操作,以便調用者可以等待它(如果需要),或者在完成此任務時預訂任務的繼續 。
為此,您將重寫上面的代碼,如下所示:
public Task<bool> CoockinRequestAsync()
{
var indicator = new ActivityIndicator();
ActivityIndicator.Show("Oooo coockin' something cool");
// This assumes Cook() returns bool...
var task = Task.Factory.StartNew(CockinService.Cook);
// Handle your removal of the indicator here....
task.ContinueWith( (t) =>
{
indicator.Hide();
}, TaskScheduler.FromCurrentSynchronizationContext());
// Return the task so the caller can schedule their own completions
return task;
}
然后,當你去使用它時,你會寫下這樣的東西:
private void SomeMethod()
{
var request = this.CoockinRequestAsync();
request.ContinueWith( t =>
{
// This will run when the request completes...
bool result = t.Result;
// Use result as needed here, ie: update your UI
}, TaskScheduler.FromCurrentSynchronizationContext());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.