2015-10-25 109 views
0

想象有一種方法如何調用異步方法

async static System.Threading.Tasks.Task Do() 
{ 
    //do sth 
    await Task.Delay(10000); 
} 

現在,當我打電話與

Do(); 

的方法它使一個新的線程?或我要創建一個線程,如下

Task.Factory.StartNew(() => Do()); 
+0

您必須像使用Task.Delay一樣使用await關鍵字。雖然第二種方法也可以,但是你不需要async修飾符。 – Camo

+1

這篇文章可能會有幫助http://blog.stephencleary.com/2013/11/there-is-no-thread.html – Grax

回答

3

Do不創建一個線程。

await之前的部分在調用線程上運行,並且在延遲期間根本沒有線程。 Task.Delay使用內部定時器,在整個操作過程中不會佔用線程。

當延遲完成後,使用ThreadPool的線程繼續執行該方法。

關於Task.Factory.StartNew,爲什麼要創建一個線程?如果需要卸載一個CPU密集型方法的線程池,然後將它的罰款(雖然Task.Run是優選的),但是如果你不那麼簡單地調用Do並等待結果:

await Do(); 

如果你堅持創建爲Do您需要使用新的線程​​:

Task.Factory.StartNew(() => Do(), TaskCreationOptions.LongRunning); 

但由於Do是釋放線程,當它到達第一等待這沒有任何意義,因爲我已經在我的博客中解釋異步方法: LongRunning Is Useless For Task.Run With async-await

+0

所以,如果我把它叫做System.Threading.Tasks.Task.Factory.StartNew(( )=> Do()); ,會創建一個新的線程?如果否,那麼在等待之前創建新線程的解決方案是什麼? –

+0

'StartNew'不創建線程。它卸載到'ThreadPool'。如果你想創建一個新的線程,你需要傳遞'TaskCreationOptions.LongRunning',但是因爲你的方法是異步的,所以毫無意義。你可以在我的博客上閱讀:[LongRunning對Task.Run沒有用處,異步等待](http://blog.i3arnon.com/2015/07/02/task-run-long-running/) – i3arnon

+0

I想要有一些線程可以讓每個線程都做一些不同的事情。 –

-1

所有我的情況是這樣的:

public void Start(Action action) 
    { 
     Token = CancellationToken.None; 
     IsRunning = true; 

     Task.Factory.StartNew(() => Do(action), TaskCreationOptions.LongRunning); 
    } 

    async Task Do(Action action) 
    { 
     while (IsRunning) 
     { 
      action(); 

      await Task.Delay(Interval, Token); 

     } 
    } 

然後調用start()方法與不同的時間間隔五種不同的動作。 這是正確使用?

+0

正如我在答覆中所說的,是的。即使「LongRunning」是多餘的。 – i3arnon

+0

你說過「但是因爲Do是一個異步方法,當它到達第一個等待時釋放線程」。當它在第一次等待時就釋放線程嗎?如果是這樣,我怎樣才能使它成爲一個活着的線程,直到應用程序運行? –

+1

你不行。異步方法的重點在於線程在不需要時被釋放。這不是一個缺點。這是一件好事。 – i3arnon