2012-09-26 117 views
3

我有這樣的方法:異步任務被凍結UI

private async Task DoSomething() 
{ 
    // long running work here. 
} 

當我這樣調用它阻止方法的UI:

Task t = DoSomething(); 

我必須做的這些之一使它非阻塞:

Task t = new Task(() => DoSomething()); 
t.Start(); 

// Or 

Task t = Task.Factory.StartNew(() => DoSomething()); 

那麼什麼是異步的點/等待時,你可以使用任務,因爲他們在框架4和使用Task.Wait()代替await

編輯: 我理解你的答案 - 但沒有真正解決我的最後一段。任何人都可以給我一個基於任務的多線程示例,其中異步/等待提高了程序的可讀性和/或流程?

+2

「異步」的目的不是多線程。它用於異步編程。您可以*使用'Task.Run'執行多線程,但'async'也可以與其他異步操作(如I/O)一起使用。基於任務的異步模式非常強大,因爲它可以以同樣的方式處理任何異步操作(無論CPU限制,I/O限制還是其他)。 –

回答

2

async方法開始它們的同步執行。 async對編寫異步操作很有用,但它不會讓代碼在另一個線程上運行,除非您告訴它。

您可以使用Task.Run調度CPU綁定工作提高到一個線程池線程。

見我async/await intro postasync FAQ以獲取更多信息。

4

你如何使用await?這不會阻止用戶界面:

private async Task DoSomething() 
    { 
     await Task.Delay(5000); 
    } 

    private async void button1_Click(object sender, EventArgs e) 
    { 
     await DoSomething(); 
     MessageBox.Show("Finished"); 
    } 

請注意,我沒有寫任何詳細的回調內容。這就是async/await

+1

這不會阻止UI,因爲Task.Delay使用在ThreadPool上運行的System.Threading.Timer。嘗試使用Thread.Sleep(5000),你會看到UI阻塞。 –

+0

順便說一句,這個想法,通過使用異步你不需要創建線程似乎是我的完整BS。等待事實只能應用於返回任務或任務的方法,這顯然表明某些時候某人將不得不創建一個新的任務! –

+0

@BrunoSantos正確,爲你+1,因爲提到'System.Threading.Timer' – NPE

0

沒有實際的代碼,這是很難告訴你這是怎麼回事,但你可以開始你的DoSomething「等待Task.Yield();」強制它立即返回,以防在第一次等待之前運行的是什麼導致了你的用戶界面問題。