2016-12-02 265 views
0

只是想確保我得到這個正確的,因爲我看到一些奇怪的行爲根據我的結果。C# - 等待和異步

public async Task<System.Net.HttpStatusCode> GetJson(Stream inputJson) 
{ 
    ...... 
    ..... 
    ... 
    var query1 = from xxx in new xxx() 
       where xxx.id == myID 
       select xxx; 
    var results1 = await query1.FindAsync(); 

    var query2 = from yyy in new yyy() 
       where yyy.id == myID 
       select yyy; 
    var results2 = await query2.FindAsync(); 
    ... 
    .... 
    ..... 
    return System.Net.HttpStatusCode.OK; 
} 

query2執行後,才query1執行完畢:

如下我定義了一個異步方法?還是並行?

+2

'query2'將在'query1'產生結果後執行。 – ThePerplexedOne

+0

@Polis:一個好的心理捷徑是:'await'意思是「異步等待」,所以它*等待。它只是等待而不是阻塞。 –

回答

2

等待後的代碼被構造爲所謂的延續。關鍵的部分是這一行:

var results1 = await query1.FindAsync(); 

FindAsync構造一個Task然後await表明,剩下的應該是工作的延續。

這意味着該方法的其餘部分將是另一個Task,並且該任務只會在第一個完成後執行。更重要的是,如果第一個任務引發異常,那麼第二個任務甚至不會啓動。

因此,您的問題的答案是:是的,query2將始終在query1完成後執行。

+0

謝謝。出於好奇,如果一個異步方法中的大部分代碼都標記爲await,是不是擊敗了異步方面?我的意思是你可能會同步運行一切,對吧?順便說一下,我暗示了一個非UI相關的過程。 – Polis

+1

嘗試從CPU的角度來看待這一點。不完全受CPU約束的操作(如數據庫或網絡操作)將返回對其執行的線程的控制權。這將讓任務管理器在同一個線程上運行其他任務,從而提高總體CPU利用率。同時做所有這些操作會降低CPU利用率,因爲當前線程將被阻塞,並且必須爲其他任務啓動另一個線程。 –

0

在你的情況下,query1將啓動,該方法將暫停執行,直到query1完成。然後纔開始query2。如果你想並行執行它們看看Task.WhenAll(...)MSDN

0

是的query2將在await query1.FindAsync()將會執行後返回結果。但要小心它會繼續的線程。這取決於。

如果你想同時做到這一點,你可以使用Task.WhenAll方法。 舉例:約WhenAll方法()你可以找到here MSDN上

var firstTask = FirstMethodAsync(); 
var secondTask = SecondMethodAsync(); 
await Task.WhenAll(firstTask, secondTask); 
// Here you can pull out Results from firstTask and secondTask. 
var firstResult = firstTask.Result; 
var secondResult = secondTask.Result; 

更多信息。