在.Net中使用处理异步事件的API时,我发现自己无法预测该库将如何扩展以适应大量对象。
例如,使用Microsoft.Office.Interop.UccApi库,当我创建一个端点时,它会在电话事件发生时获取事件。现在假设我想创建1000个端点。每个端点的事件数量很少,但是API中幕后发生的事情是否能够跟上事件流?我不知道,因为它从来没有说明它是如何架构的。
假设我想在主线程中创建全部1000个对象。然后,我想把Login方法放到一个大的线程池中,这样所有的对象都可以并行登录。然后,一旦所有对象都已登录,下一阶段将开始。
API引发的事件回调是否发生在原始创建线程中?单独的线程池?或者是我用ThreadPool.QueueUserWorkItem访问的同一个线程池?
我把每个对象放在它自己的线程中会不会更好?在每个线程中分组几个对象?或者,只要在主线程中创建全部1000个对象,然后通过.Net魔法,一切都会好起来吗?
谢谢
发布于 2008-10-22 21:02:23
来自互操作程序集的事件只是COM连接点的包装器。来自连接点的调用到达的线程取决于在该连接点上建议的对象的线程模型。COM将确保对此进行正确的线程切换。
如果您的对象是在主线程上实现的,那么所有事件都应该到达同一个线程。在.Net中,主线程通常是STA。如果您希望调用从COM线程池(我认为与CLR线程池相同)到达随机线程,则需要在配置为MTA的线程上创建对象。
我强烈建议不要为每个对象创建线程: 1)如果您将这些线程创建为STA,则每个线程都将有一个消息队列,占用系统资源;2)如果您将它们创建为MTA,则没有什么能保证事件调用将到达您的线程;3)您将有1000个空闲线程什么也不做,只是等待事件关闭;以及4)启动和关闭所有这些线程将在您的应用程序上产生可怕的性能成本。
发布于 2008-10-22 20:43:52
这真的取决于很多东西,主要是你的硬件有多强大。线程池确实有一定数量的线程(您可以增加),它将使您的应用程序可用。因此,如果所有的事件都同时触发,那么在线程池等待线程再次空闲时,其中一些事件很可能会等待一段时间。权衡的是,您也没有一直创建新线程的性能影响。可能创建1000个线程也不是正确的答案。
事实可能会证明这是理想的,这既是因为重用线程的性能提升,也是因为同时运行1000个线程可能会占用更多的内存/ CPU。
发布于 2008-10-23 13:46:28
我只想指出,在.NET 2.0和更高版本中,可以使用ThreadPool.SetMaxThreads()以编程方式增加线程池中的最大线程数。考虑到这一点,您可以对线程数量设置一个硬性的上限,从而确保调度程序不会被开销压垮。
在这种情况下更有用的是,您可以使用ThreadPool.SetMinThreads()设置最小线程数。有了这个,你就可以确保你只需在应用程序启动时支付Franci所说的“可怕的性能代价”一次。你可以根据预期的用户数量峰值来权衡这一点,因此确保你不会创建大量的新线程。
一个新线程的创建不会毁了你。我担心的是需要同时创建许多线程的情况。如果你可以说这只会在启动时发生,那么你就是金子。
https://stackoverflow.com/questions/227446
复制相似问题