我有一个TPL任务,做两件事。首先,它调用Web服务。其次,它将一些数据插入数据库。我一次启动多达20个任务一次又一次地做同样的事情。他们全天所做的就是调用Web服务并将数据插入数据库。
我对.NET中的TPL很新。我已经完成了后台工作进程和异步Web服务的一些事情。
Web服务调用和数据库插入都是在运行任务的线程内阻塞调用。
据我所知,在使用Tasks时,.NET会为您管理一个线程池。是?
如果我使用async和await()进行服务调用和数据库调用而不是阻止调用,那么线程池是否可以使用更多的线程?
我的理论(我不知道为什么我认为这个)是线程在等待阻塞Web服务时忙于什么都不做,并且不能暂时将其资源返回池中。但我想知道任务是否在等待异步调用来完成主要任务线程是否能够在等待时切换到让其他东西进程。
我的理论是对的吗?或者我正在制作东西?
我正在使用c#和.NET 4.0,但如果需要,我可以使用4.5。
如果我做了,那么线程池是否可以使用更多的线程
使用async和await()代替的服务调用和数据库调用
让他们阻止通话?
这取决于你的意思 “利用async-await”。
当你使用 Task.Run
在幕后, Task
班级使用 ThreadPool
使用a卸载工作 ThreadPool
线。
如果您的服务没有公开真正的异步api并且您使用了 Task.Run
为了排队你的工作,你仍然会阻止线程池线程做IO绑定工作,无论使用什么 async-await
。在你的问题中,你声明两个调用都是阻塞调用,在这种情况下答案是否定的,用于阻止调用的线程池线程仍然会被阻止。
如果您的服务和数据库调用是真正的异步API(不使用任何额外线程来完成其工作),您可以利用 async-await
,就像你 await
在其中一个调用上(并且您根本不需要使用Task.Run),当前线程将控制权返回给调用者,并且可以同时用于执行更多工作。如果是这种情况,那么是的。
我的理论(我不知道为什么我认为这个)是线程在等待阻塞Web服务时忙于什么都不做,并且不能暂时将其资源返回池中。但我想知道任务是否在等待异步调用来完成主要任务线程是否能够在等待时切换到让其他东西进程。
你的理论是正确的。如果排队的线程池工作的主要工作是发出IO绑定请求,那么它的大部分时间花费只是阻塞直到请求完成。
当你 await
一个 Task
,控制产生回调用者。让我们假设您的服务调用是一个REST调用,您可以使用 HttpClient
它暴露了真正的非线程消耗异步方法,如 GetAsync
, PostAsync
,当你 await
这些调用,你的调用线程被释放,同时做更多的工作。
如果所有应用程序的任务都被阻止,则每个任务都将使用线程池中的线程。
如果所有任务定期 await
,线程池不需要为每个任务使用线程。
当你的代码 await
如果某个操作尚未完成,则保存方法的状态,以便可以在任何其他线程上恢复该状态。
空闲的线程池线程会在一段时间后释放,因此实际的线程会遇到一个 await
可以在方法调用时从线程池中释放 await
还在运行
将所有这些放在一起,异步版本的例程可以用更少的线程完成相同的工作(假设工作负载有足够的时间平衡等待与旋转CPU)。
此代码运行100个执行同步等待的任务:
var numTasks = 100;
for (int i = 0; i < numTasks; i++)
{
Thread.Sleep(5);
Task.Run(() =>
{
Thread.Sleep(5000);
Interlocked.Decrement(ref numTasks);
});
}
while (numTasks > 0) Thread.Sleep(100);
对于异步等待,将其更改为:
Task.Run(async () =>
{
await Task.Delay(5000);
Interlocked.Decrement(ref numTasks);
});
在我的系统上,异步版本将峰值线程数增加了一半,并且花费20%的时间来执行相同的“工作”。
答案是肯定的。虽然从技术上讲它并没有“等待”异步操作完成(否则对异步没有任何好处)。在引擎盖下有一个回调委托,它在异步操作完成时运行,这使得你的调用线程可以不受阻塞地继续运行。它是异步/等待魔法,将这些“延续”变成线性的代码片段。
因为您正在使用线程池线程,当它命中等待时,线程将返回到线程池。这里需要注意的是,正常的行为是当等待操作完成时它将尝试返回到它启动的线程(现在可能被另一个任务使用),因此您可能会发现延迟问题结果回来,因为线程池线程现在被绑定启动其他任务。随着时间的推移,线程池将尝试调整可用线程的数量以满足需求,但是如果你的工作突然发生,你可能会发现这种情况不会发生得太快。结果显然是性能不佳,因为您可能只有少量线程可用。