我正在开发一个远程扫描服务器并收集有关它们的元数据的应用程序。
我正在尝试编写可在我们的服务器上很好地扩展的代码。我正在使用TPL同时处理多个作业。我遇到的问题是,每个“作业”都花费一半的时间等待I / O操作完成。
如果这些操作提供了Async或Begin / End接口,但它们没有提供,那么这将非常容易修复。情侣样本:
System.IO.Directory.GetAccessControl
Win32API调用,例如FindFirstFile http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx和FindNextFile http://msdn.microsoft.com/en-us/library/windows/desktop/aa364428(v=vs.85).aspx
如何确保我的应用程序在此方案中执行更多操作?我应该为这些创建包装器以便支持Async,并且这样它们将被发送以便在线程中进行处理。 我应该尝试TPL实现生产者/消费者,以便所有这些I / O调用同时执行吗? TPL是否足够聪明以创建更多线程,因为大多数线程都不会做任何事情? 或者也许在这些工作中,我应该将工作添加到ThreadPool进行处理?
答案 0 :(得分:2)
如果您将大部分时间花在没有异步等效的IO绑定操作上,那么加速它们的唯一方法就是使用大多数时间都被阻塞的多个线程。
但是根据IO的性质,你可能根本不会获得任何加速。例如,如果IO正在访问本地磁盘,那么使用单个线程很可能是最有效的选择。另一方面,如果您正在访问远程计算机并且不受网络带宽的限制,那么使用多个线程可能是最佳选择。
TPL听起来像是正确的解决方案,但TPL的哪一部分取决于您的代码。也许使用Parallel.ForEach()
同时处理多个作业将是正确的解决方案。或者您可能希望使用Task
并行运行单个作业的某些部分。如果不了解更多细节,很难说。
我是否应该为这些创建包装器以便支持Async,这样它们就会被发送到线程中进行处理。
不,不要那样做。如果你在另一个线程上启动阻塞Task
,然后使用await
释放当前线程,那么你没有获得任何东西(假设这是一个服务器应用程序)。有关详细信息,请参阅Should I expose asynchronous wrappers for synchronous methods?
TPL是否足够聪明以创建更多线程,因为大多数线程都不会做任何事情?
是的,如果当前的线程被阻止,TPL往往会使用更多线程。但与此同时,您很可能希望限制线程数(通常通过设置类似MaxDegreeOfParallelism
的内容),具体取决于您正在执行的IO类型。