2

我正在开发一个远程扫描服务器并收集有关它们的元数据的应用程序。

我正在尝试编写可以在我们的服务器上很好扩展的代码。我正在使用 TPL 同时处理多个作业。我遇到的问题是这些“作业”中的每一个都花费一半的时间等待 I/O 操作完成。

如果这些操作提供 Async 或 Begin/End 接口但它们没有,这将很容易解决。几个样本:

如何确保我的应用程序在这种情况下做得更多?我是否应该为这些创建包装器以支持异步,并且这样它们将被发送以在线程中进行处理。我应该尝试 TPL 实现 Producer/Consumer 以便同时执行所有这些 I/O 调用吗?TPL 是否足够聪明以创建更多线程,因为它们中的大多数都不会做任何事情?或者也许在这些作业中的每一个中我应该将作业添加到 ThreadPool 进行处理?

4

1 回答 1

3

如果您将大部分时间花在没有异步等效项的 IO 绑定操作上,那么加速它们的唯一方法是使用大多数时间被阻塞的多个线程。

但根据该 IO 的性质,您可能根本无法获得任何加速。例如,如果 IO 正在访问本地磁盘,那么使用单线程很可能是最有效的选择。另一方面,如果您正在访问远程计算机并且不受网络带宽的限制,那么使用多线程可能是最佳选择。

TPL 听起来像是正确的解决方案,但 TPL 的哪一部分取决于您的代码。也许同时处理多个工作Parallel.ForEach()将是正确的解决方案。或者,您可能希望使用Tasks 并行运行单个作业的某些部分。不知道更多细节很难说。

我是否应该为这些创建包装器以支持异步,并且这样它们将被发送以在线程中进行处理。

不,不要那样做。如果您Task在另一个线程上开始阻塞,然后使用 释放当前线程await,那么您将一无所获(假设这是一个服务器应用程序)。有关更多信息,请参阅我应该为同步方法公开异步包装器吗?

TPL 是否足够聪明以创建更多线程,因为它们中的大多数都不会做任何事情?

是的,如果当前线程被阻塞,TPL 倾向于使用更多线程。但与此同时,您很可能希望限制线程数(通常通过设置类似MaxDegreeOfParallelism),具体取决于您正在执行的 IO 类型。

于 2013-08-23T17:42:38.963 回答