Task的并发数量到底是多少呢?
是不是根绝CPU的核心数来决定的,投递10000个任务,然后在任务里Thread.Sleep(1000)睡1秒钟,再添加ListBox里面的Item,显示是两个两个都添加。CPU是G3260
如果Task的并发数量是根据CPU的核心数来决定的那么可不可以调节他的并发线程数量
for (int i = 0; i < 10; i++) { Task.Factory.StartNew(() => { Thread.Sleep(200); var r = new Random(); this.listBox1.BeginInvoke((Action)(() => { this.listBox1.Items.Add(r.Next()); })); }); }
比如这段代码,运行起来实际只有两个Task在并发运行
你什么地方能看到有两个task在运行?你应该看到的是线程数吧。
你代码中间那么大一个thread.sleep,这明显的就给了task一个很好的借口去做别的事了。
更新到ListBox里面的,sleep就是为了看效果,两秒钟后ListBox只添加了两个Item,然后等了一会又添加了两个Item
@梦里的畅泳: 给个hint试下 TaskCreationOptions.LongRunning
@Daniel Cai: 这样的话确实是并发数出来了,比如我投10000 设置 TaskCreationOptions.LongRunning 后等了两秒钟然后ListBox一直加Item不停 这个并发不会是10000吧?
@Daniel Cai: 暂时用信号量解决并发问题, TaskCreationOptions.LongRunning 设置了后好像感觉并发就是投递的Task的数量,但是想想还是不太可能。暂时把 TaskCreationOptions.LongRunning设置上,然后用Semaphore来限制
@梦里的畅泳: 默认情况下所谓的2个2个的加可能因为你的cpu是双核的,这个时候你的task创建出来没有任何办法得知应该怎么样运行。当一旦添加了这个提示后就告诉了task这些任务可以直接用线程池,那么此时执行和threadpool没太大区别,并发量取决于你线程池的设定及cpu核数(默认5k/core)。但最后回写到ui上由于你的代码逻辑,所以最后ui呈现的时候还是由ui线程一点点的输出出来的。
在你的场景下我觉得不应该用taskfactory和semaphore,这种可能会导致大量的执行最后都等待进入临界区。你可以尝试下用并行库的Parallel.ForEach+ParallelOptions来控制。
task他是任务。需要如何并发是你程序来选择的。你可以在内存没爆掉的情况下,new 任意多个task。
如果你说的微软自带的并行库。默认是按照cpu个数来设置最大并发数量的,但是你也可以自己手动设置任何大小。
内存肯定是没有爆掉的,代码也是New了很多个task但是同时工作的只有两个
@梦里的畅泳: 什么叫同时工作的呢。running状态下的task只有2个么
@calvinK: 对的,您看我后面贴的代码
@梦里的畅泳: 这个测试代码,如楼下所说。不太合格呢。
tasks;
for i=0;i<100
task=new task()=>{ sleep(100000)};
tasks.add(task)
timer callback
tasks.count(state==running)
@calvinK:
var tasks = new List<Task>(); for (int i = 0; i < 100; i++) { tasks.Add(Task.Factory.StartNew(() => { Thread.Sleep(100000); var r = new Random(); })); } var count = tasks.Count(m => m.Status == TaskStatus.Running); MessageBox.Show(count.ToString());
count为0
@梦里的畅泳: 大哥,刚add,就计算runing的数量,当时是0咯。。。。
我的伪代码:timer callback,是让你task启动一定时间之后,在看。
任务安排下去时候,也是要时间才能启动的呀
ThreadPool.SetMinThreads(10, 10);