2015-10-25 202 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