2011-05-31 50 views
4

我正在玩新的異步CTP位,我不能讓它與服務器端或只是命令行程序(和所有的例子是WPF或Silverlight的)工作。例如,像一些瑣碎的代碼:立即等待立即移動到下一個語句

class Program { 
    static void Main() { 
     Program p = new Program(); 
     var s = p.Ten2SevenAsync(); 
     Console.WriteLine(s); 
    } 

    private async Task<int> Ten2SevenAsync() { 
     await TaskEx.Delay(10000); 
     return 7; 
    } 
} 

返回並打印System.Threading.Tasks.Task 1 [System.Int32]`,而不是等待10秒,並返回圖7(如我所期望的)。必須是明顯的我缺少的東西。

回答

10

基於的await碼的整點是(回調),它的確是「的時候,這是完成執行下一個東西」,並「阻止當前線程,直到這個已經完成」。

因此,從Ten2SevenAsync您得到一個任務,但該任務尚未完成。將任務寫入控制檯並不意味着它會等待它完成。如果你想在任務的完成阻止:

static void Main() { 
    Program p = new Program(); 
    var s = p.Ten2SevenAsync(); 
    Console.WriteLine(s.Result); 
} 

或更明確:

static void Main() { 
    Program p = new Program(); 
    var s = p.Ten2SevenAsync(); 
    s.Wait(); 
    Console.WriteLine(s.Result); 
} 
+1

@Felix - 是的,謝謝,我很熟悉。它通過退出實際方法起作用。如果您退出「Main」(只有工作線程/任務),則會丟失進程。它不是***的目的就是像同步代碼一樣行事* - 它只是爲了方便寫同步代碼。 – 2011-05-31 06:15:18

+0

@Felix - 如果你「等待」,你只能得到一個「int」。但是,如果你'等待'你已經退出'Main()' - * boom *;沒有更多的過程。強調:「等待」意味着「將此作爲回調」,***不會***「阻止,直到完成」。但是,您的代碼示例(問題)***不會顯示***'Main'作爲'async'方法 - 因此任何異步使用都必須是明確的。說實話,無論如何,將'Main'設置爲'async'方法是一個壞主意。 – 2011-05-31 06:17:19

+0

對不起;我誤解了你說的話......我刪除了我的愚蠢評論,並將其標記爲答案:) – Felix 2011-05-31 06:17:56

2

我相信,你只需要你的榜樣4號線更改爲:

var s = await p.Ten2SevenAsync(); 
+0

更糟糕!我爲Main添加了等待和異步,現在它根本不打印任何東西。感覺像「等待」立即返回給調用者:來自Ten2Seven的任務,並且沒有任何(無效)到OS。 – Felix 2011-05-31 05:48:53

+4

爲什麼這會得到upvoted? – tofutim 2011-05-31 05:51:53

+4

如果你使'Main'成爲一個異步方法,它會很早退出'Main'。而且,由於任務發生在工人身上,您將會失去整個過程。 – 2011-05-31 06:00:22

1

s是一個異步任務的參考。我還沒有玩過這個遊戲,所以我不確定語法,但是會有s的成員可以檢查任務是否完成,然後檢索結果。

+0

你是對的; '.IsCompleted'和'.Result'(注意'.Result'還包含一個隱含的'.Wait()') – 2011-05-31 06:20:27