我对.NET中的TPL来说相当新鲜.我已经做了一些后台工作流程和异步Web服务的东西.
我明白,在封面下,当您使用任务时,.NET会为您管理一个线程池.是?
如果我使用async和await()进行服务调用和数据库调用,而不是阻止调用,那么线程池有更多的线程吗?
我的理论(我不知道为什么我认为这一点)是线程正忙着等待阻塞的Web服务,不能将其资源暂时返回到池中.但是我想知道任务是否等待异步调用来完成主任务线程是否能够切换到让等待的其他东西进程.
我的理论是对的吗还是我做的东西?
我使用c#和.NET 4.0,但如果需要,我可以去4.5.
解决方法
Would the thread pool have more threads at its disposal if I made the
service call and database call with async and await() instead of
making them blocking calls?
这取决于你的意思是“使用异步等待”.
当您使用Task.Run,幕后,Task类使用ThreadPool使用ThreadPool线程卸载工作.
如果您的服务没有暴露一个真正的异步api,并且您使用Task.Run排队您的工作,您仍将阻止线程池线程执行IO绑定工作,而不管使用async-await.在你的问题中,你声明这两个呼叫都是阻塞调用,在这种情况下答案是否定的,用于使这些阻塞调用的线程线程仍然被阻止.
如果您的服务和数据库调用是真正的异步API(一个不消耗任何额外的线程来执行其工作),您可以利用async-await,就像在等待其中一个调用时一样(并且您不应该需要使用Task.Run与它们一起),当前线程将产生回调给调用者,并可以在同一时间内使用更多的工作.如果是这种情况,那么是的.
My theory (and I’m not sure why I think this) is that the thread is busy doing nothing while waiting on the blocking web service and can’t return its resources temporarily to the pool. But I wonder if the Tasks were waiting for async calls to finish whether the main Task thread would be able to switch to let other stuff process while waiting.
你的理论是正确的如果排队的线程池的主要工作是创建一个IO绑定请求,那么大部分时间的消耗简单地阻塞直到请求完成.
等待任务时,控制权返回给调用者.假设您的服务调用是一个REST调用,您可以使用HttpClient来显示真正的非线程消费的异步方法,如GetAsync,PostAsync,并且当您等待这些调用时,您的调用线程将被释放以在此期间进行更多的工作.