2016-12-15 104 views
2

我正在學習異步並等待在C#中的操作。當它處理多個異步操作時,我無法理解執行流程。例如:我有我的c#應用程序中的下面的代碼。瞭解Aync並在C中等待#

await repository.GetAsync(values);//execute for 10 sec        
var result = repository.setAsync(data); //20 sec 
dataresult = await repository.GetAsync(result);//execute for 10 sec 

我在這裏有三個異步調用。

根據我的理解,每個通話都會有一個回調,這不會等待一個動作完成。

那麼我如何確保行動完成?

repository.setAsync將在repository.GetAsync(values)完成其執行之前執行?或者這隻會在repository.GetAsync(values)執行完成後才執行?

那麼執行的順序是什麼?

1)

await repository.GetAsync(values);//started await method execution,since there is no callback it will not set and will start execute the next before complete this.        
    var result = repository.setAsync(data); //will execute for 20 sec. Once completed will go to previous thread and complete that. 

2)

await repository.GetAsync(values);//started await method execution,complete it and move to the next line. 
    var result = repository.setAsync(data); //will execute for 20 sec. 

當您執行同步的東西,你等待它在移動到另一個任務之前完成。當你異步執行某些東西時,你可以在完成之前移動到另一個任務。但是在這裏,爲了異步它等待操作完成。爲什麼這個矛盾?

我只想在操作完成後返回數據收集。 我覺得這是違反消防而忘了。這兩者是相同還是不同的概念? 按以下連結reference

該關鍵字的await不會阻塞線程直到任務完成 。

但從這裏發佈的答案,我明白這將暫停執行。這是真的嗎?我錯過了什麼嗎?

+0

簡單地說:'await'是一個「異步等待」,所以*方法*將等待它完成,但*線程*未被阻止。您可能會發現我的[異步介紹](http://blog.stephencleary.com/2012/02/async-and-await.html)很有幫助。 –

回答

5

根據我的理解,每個調用都會有一個回調,這不會等待一個動作完成。

當您使用await時,代碼將在繼續前等待操作完成。這是您處理數據依賴性的方式 - 任務需要先前任務的結果在開始處理之前可用的情況。唯一沒有等待的操作是result,因此GetAsync(result)必須以Task<T>作爲其參數,其中T是方法返回的任何形式的類型。

注意

如果按照await代碼並不需要在UI線程上執行,你應該呼籲Task你正在等待ConfigureAwait(false)。爲什麼這是最佳做法? Stephen Cleary提供了一個很好的解釋它的blog post on the topic of async/await deadlocks

這也很可能是你缺少await第二行和data在第一行的任務:

var data = await repository.GetAsync(values).ConfigureAwait(false); 
var result = await repository.SetAsync(data).ConfigureAwait(false); 
dataresult = await repository.GetAsync(result).ConfigureAwait(false); 

那麼,什麼是回調觀火,忘記這裏?

如果回調await通話,這是可能的之前,當你啓動一個任務,做別的事情,然後await這個任務,你有機會做更多的工作在「發射和忘記」之間發生並將結果返回。這裏的關鍵是在中間必須沒有數據依賴:

var dataTask = repository.GetAsyncOne(values); // Fire and forget 
// Do something else in the middle 
var result = await repository.SetAsync(data).ConfigureAwait(false); 
// If the task has completed, there will be no wait 
var data = await dataTask.ConfigureAwait(false); 
+0

未等待的唯一操作是結果。你能詳細說明一下嗎?我無法看到這行和其他行之間的代碼有任何區別。請幫助 –

+0

@TomCruise代碼中的中間行表示'var result = repository.setAsync(data);',即沒有'await'。假設'setAsync'是一個'async'方法,它的簽名是'Task ',所以'result'是一個任務。 – dasblinkenlight

+0

因此,異步操作會使線程等待操作完成?那麼回調和火災的概念是什麼,在這裏忘記? –