2013-06-30 39 views
-1

我有,我需要在一個C#/ XAML應用程序在後臺線程運行的活動,所以我這樣做:無法獲得C#任務exection流正常工作

Task.Factory.StartNew(() => ImportFile()); 

我m將任務值返回到另一位代碼,然後在之後需要採取行動基於線程的工作已完成。代碼如下所示:

Action<Task> finalise = async delegate { await FinishImport(dbList); }; 
dbList.ImportFileAsync().ContinueWith(finalise); 

當我運行的代碼,但是,正在後臺線程完成之前執行的FinishImport調試語句。

什麼我誤解嗎?我認爲ContinueWith的全部要點是它會在目標任務完成後執行延續代碼。

+0

您可以包括演示此問題短,但完整的示例代碼?否則,回答這個問題需要很多猜測。 – svick

+0

@PhilipColmer:你是否從特定的源獲得了'Task.Factory.StartNew'的想法?想知道爲什麼你有這樣的代碼... –

+0

Task.Factory.StartNew的原因是因爲我最初嘗試過Task.Run,​​並且遇到了相同的延續代碼問題,實際上並沒有等待。此外,我需要導入文件有點「火,忘了」,因爲如果應用程序被暫停然後重新啓動,我需要重新啓動以便能夠再次啓動ImportFile,並且我的頭部與執行流的扭曲思想爆炸了一點。 「線程結束後」 –

回答

1

您應該在async代碼中使用Task.Run而不是Task.Factory.StartNewTask.Run理解async方法而StartNew會返回一個Task表示async方法僅僅是個開始。

作爲一個側面說明,它通常是最好不要有隱藏庫方法中Task.Run

此外,它更容易使用awaitContinueWith。並且async方法應以「Async」結尾。

所以,應用這些準則使你的代碼看起來像:

await Task.Run(() => dbList.ImportFileAsync()); 
await FinishImportAsync(dbList); 
+0

對不起,但這沒有奏效。我看到的執行順序是: 1.在這兩個等待之前的調試語句。 2.「ImportFileAsync」中的調試語句確認代碼執行的開始。 3.來自「FinishImportAsync」的調試語句。 4.「ImportFileAsync」中的更多調試語句確認任務仍在運行! 這是我一直打的磚牆,這就是爲什麼我嘗試使用Task.Factory.StartNew而不是Task.Run(我曾嘗試過)。無論是等待還是ContinueWith實際上都在等待後臺任務完成。 –

+0

最可能發生的事情是'ImportFileAsync'有一個錯誤,它正在返回,而還有其他工作正在進行。試着問一個新問題,發佈一個最小的問題再現。 –

+0

我想我找到了原因。由於對GetFileAsync和OpenReadAsync的調用,ImportFileAsync需要是異步的。這搞亂了執行流程。我現在重構了代碼,以便Task.Run在主循環的ImportFileAsync內完成,而不是整個代碼。我現在只是去「等待dbList.ImportFileAsync();」並已修復它。當我試圖編輯原始問題時,我想到了這一點:-) –

0

什麼ImportFileAsync()呢?

finalise會的ImportFileAsync()線程運行後會結束

如果 ImportFileAsync(){ Task.Factory.StartNew(() => ImportFile());}

然後ImportFileAsync將調用一個新的線程ImportFile()然後退出它不會等待ImportFile() 完成

你想做的事

Task.Factory.StartNew(() => dbList.ImportFile()).ContinueWith(finalise);

+0

「這不太合適。當Task執行完成時,它不會結束任何'Thread','Thread'保留在'ThreadPool'中。 – svick

+0

@svick,會不會說範圍更好?任務完成並且線程返回到線程池。實際上講是一樣的.. – Nahum

+0

這不會更好,因爲範圍與此沒有任何關係 – svick