好的,我确信有一个简单的解释,而且我缺乏适当的线程教育让我无法看到它,所以请光顾我...
我的应用程序处理数据Feed。当一个新的数据包进入时,一个调度程序收集它,并引发一个正确的监听器可以接收并执行它需要做的事件。
所以现在我正在尝试模拟实时源以执行一些测试。我创建了一个类,根据活动列表的数量为调度程序提供数据包。
这是我用来启动Feed()方法的代码,该方法位于内存中并在每个给定的时间间隔内生成一个数据包:
foreach (var item in Listeners)
{
object listener = item;
Task.Factory.StartNew(()=> Feed(listener), TaskCreationOptions.LongRunning);
}
Feed()方法的工作原理如下:
while(run)
{
packet = GenerateThePacket(listener.Id); // Make a packet with the listener id
FeedHandler.OnPacketRecieved(this, packet); // Raises the FeedHandler's event as if it came from outside.
Thread.Sleep(1000/interval) // interval determines how many packets per second
}
因此,如果我有100个侦听器,它将启动100个Feed()实例,每个实例具有不同的侦听器ID,并以请求的间隔同时启动PacketRecieved事件。
我猜你们中的许多人已经知道它有什么不好,但无论如何我会解释这个问题: 当我使用1或2的间隔时,效果很好。当我选择10(即每100毫秒一个数据包)时,它无法正常工作。每个线程以不同的间隔启动,其中创建的最新线程运行良好且快速(10 /秒),并且第一个线程创建工作真正慢(1 /秒或更短)。
基本上,我认为100个线程不能同时运行,所以他们只是在等待......我想。
那么,到底发生了什么,以及如何实现一个真正的Feed生成器,它可以同时为100个听众模拟每秒10个数据包。
谢谢大家
答案 0 :(得分:1)
我认为你是从错误的角度接近这个......
阅读这些内容:
http://blogs.msdn.com/b/pfxteam/archive/2010/04/21/9997559.aspx(链接到那里的pdf)
http://www.sadev.co.za/content/pulled-apart-part-vii-plinq-not-easy-first-assumed
简而言之,Task库将从线程池中获取一个线程,如果一个线程不可用,则任务将排队,直到一个线程可用.....所以,线程数可以同时运行取决于在您的系统和线程池的大小。
对我来说,有两种方法可以使用:使用Parallel.ForEach静态方法或使用上面文章中描述的PLinq AsParallel()选项。在一天结束时,由您决定使用哪一个。
使用plinq ......这样的事情:
var parallelQuery = Listeners.AsParallel().Select(item=> Feed(item)); //creates the parallel query
parallelQuery.ForAll(item=> <dosomething>); //begin the parallel process and do whatever you need to do for each result.
您的Feed方法/对象可能如下所示:
while(run)
{
packet = GenerateThePacket(listener.Id);
FeedHandler.OnPacketRecieved(this, packet); // Raises the FeedHandler's event as if it came from outside.
//No more Thread.Sleep
}
这只是一个基本的介绍,但我上面添加的链接非常有用且信息丰富。这取决于您使用哪种方法。 请注意,您可以在上面的链接中添加其他选项....
希望这有帮助!