2012-11-08 198 views
9

我在C#中有以下代碼,VS2012,WPF 4.5。 我的期望是,.ContinueWith將在任務完成後執行(這是延續的全部目的,不是嗎?)。。繼續任務完成之前啓動

這應該在finalResult的值爲2。

int myTestInt = 0; 

Task task = Task.Factory.StartNew(async() => 
{ 
    myTestInt = 1; 
    await Task.Delay(TimeSpan.FromSeconds(6)); 
    myTestInt = 2; 

}).ContinueWith(_ => 
    { 
     int finalResult = myTestInt; 
    }); 

實際上,finalResult被賦值爲1。所以看起來延續已經開始於await聲明。

這是預期的行爲?我在這裏錯過了什麼嗎?在任務完成後,我不能依靠ContinueWith啓動嗎?

更新:

賈斯汀的回答只是激勵我檢查以下內容:

int myTestInt = 0; 
Task task=Task.Factory.StartNew(async() => 
{ 
    myTestInt = 1; 
    await Task.Delay(TimeSpan.FromSeconds(6)); 
    myTestInt = 2; 
}); 

task.Wait(); 
int result2 = myTestInt; 

finalResult仍設置爲1,有沒有辦法能夠可靠地等待包含await s到完成任務?

+4

我想你應該直接調用'Task.Delay'而不是'await'關鍵字。 –

+2

你會注意到'_'實際上是一個'Task ',它完全支持Justin在說什麼...... –

+0

事實上,使用Task.Delay(6)會產生預期的結果,但不會等待6秒。我認爲刪除整條線幾乎是一樣的。 –

回答

10

當你傳遞一個async委託Task.Factory.StartNew,返回Task僅代表委託(直到一次await件事情是不是已經完成)的第一部分。

但是,如果您將async委託人傳遞給新的Task.Run方法(由於此原因而包含此方法),則返回的Task表示整個委託人。所以你可以像你期望的那樣使用ContinueWith。 (儘管await通常比ContinueWith更好)。

有關StartNewRun的更多信息,請參見Stephen Toub's post on the topic

+0

鏈接的帖子說得很清楚。謝謝!! –

4

await將立即將控制權返回給調用函數,在本例中爲調用函數的StartNew。這意味着任務將完成並執行ContinueWith。 如果您確實需要在ContinueWith之前完成任務,那麼請不要等待Task.Delay。

+0

我認爲你是對的 - 等待標記目前的任務已完成。雖然它不是(至少不是從語義的角度來看)。正如await是今天所有軟件的基本組成部分,這意味着永遠不會依賴ContinueWith。你不覺得,這是一個錯誤? –

-1

我在MSDN看到這個::-)

public async void button1_Click(object sender, EventArgs e) 
{ 
    pictureBox1.Image = await Task.Run(async() => 
    { 
     using(Bitmap bmp1 = await DownloadFirstImageAsync()) 
     using(Bitmap bmp2 = await DownloadSecondImageAsync()) 
     return Mashup(bmp1, bmp2); 
    }); 
} 

所以不要忘記「異步()」!

+0

他的代碼有'異步',他的問題是他正在使用'TaskFactory',它沒有一個超載,它接受'Task.Run'具有的'Func '或'Func >'。 –

相關問題