您是否可以立即调用过多的Delegate.BeginInvoke?

时间:2010-06-12 18:00:59

标签: c# .net

我正在清理一些旧代码,将其转换为异步工作。

psDelegate.GetStops decStops = psLoadRetrieve.GetLoadStopsByLoadID;
var arStops = decStops.BeginInvoke(loadID, null, null);
WaitHandle.WaitAll(new WaitHandle[] { arStops.AsyncWaitHandle });
var stops = decStops.EndInvoke(arStops);

上面是我正在为异步工作做的一个例子。我的计划是让近20名不同的代表参加竞选。所有人都会致电BeginInvoke并等到他们全部完成后再致电EndInvoke

我的问题是会有这么多代表运行导致问题吗?我知道BeginInvoke使用ThreadPool来完成工作,并且限制为25个线程。 20是在该限制之下,但很可能系统的其他部分也可能使用ThreadPool中的任意数量的线程。

谢谢!

2 个答案:

答案 0 :(得分:2)

不,ThreadPool管理器旨在处理这种情况。它不会让所有线程池线程同时运行。它开始允许尽可能多的线程运行,因为你有CPU核心。一旦完成,它就允许另一个运行。

如果活动线程未完成,则每半秒进入一次。它假设它们被卡住并允许另一个运行。在2核CPU上,您现在有3个线程正在运行。

在2核CPU上获得最多500个线程需要相当长的时间。您必须拥有超过4分钟未完成的线程。如果您的线程表现那样,那么想要使用线程池线程。

答案 1 :(得分:1)

当前默认的MaxThreads是每个处理器250,所以除非您的应用程序只是向BeginInvoke发出调用,否则应该没有限制。见http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx。此外,线程池将在创建新线程之前尝试重用现有线程,以减少创建新线程的开销。如果你调用快速,你可能不会看到线程池创建了很多线程。

对于长时间运行的任务或阻塞任务,通常最好避免线程池并自己管理线程。

但是,尝试安排许多线程可能无法在大多数当前机器上产生最佳结果。