【发布时间】:2014-09-15 15:54:56
【问题描述】:
我按照MSDN 的示例制作了自己的演示,用于创建限制并发的任务调度程序。 maxDegreeOfParallelism 设置为 2。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TaskSchedulerThatLimitsConcurrency
{
class Program
{
static void Main(string[] args)
{
// Create a scheduler that uses two threads.
LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(2);
List<Task> tasks = new List<Task>();
// Create a TaskFactory and pass it our custom scheduler.
TaskFactory factory = new TaskFactory(lcts);
CancellationTokenSource cts = new CancellationTokenSource();
// Use our factory to run a set of tasks.
Object lockObj = new Object();
for (int i = 0; i < 4; i++)
{
var myFactory = new TaskFactory(lcts);
Task t = myFactory.StartNew(() =>
{
if (cts.IsCancellationRequested)
return;
lock (lockObj)
{
MakeTest(i, 1);
}
}, cts.Token);
tasks.Add(t);
}
for (int i = 0; i < 4; i++)
{
var myFactory = new TaskFactory(lcts);
Task t1 = myFactory.StartNew(() =>
{
if (cts.IsCancellationRequested)
return;
lock (lockObj)
{
MakeTest(i, 2);
}
}, cts.Token);
tasks.Add(t1);
}
// Wait for the tasks to complete before displaying a completion message.
Task.WaitAll(tasks.ToArray());
Console.WriteLine("\n\nSuccessful completion.");
Console.Read();
}
private static void MakeTest(int i, int p)
{
StringBuilder sb = new StringBuilder();
sb.Append(i.ToString() + "_" + p.ToString());
Console.WriteLine(sb.ToString());
}
}
}
结果是
任务 t1 和 t2 几乎相同。区别在于MakeTest(i, 1) 和MakeTest(i, 2)。我想知道我可以使用第二个 for 循环来添加任务吗?
我使用了下面的代码,但显然结果是错误的。
for (int j = 0; j < 2; j++)
{
for (int i = 0; i < 4; i++)
{
var myFactory = new TaskFactory(lcts);
Task t1 = myFactory.StartNew(() =>
{
if (cts.IsCancellationRequested)
return;
lock (lockObj)
{
MakeTest(i, j+1);
}
}, cts.Token);
tasks.Add(t1);
}
}
结果:
问题:
- 为什么我的原始代码没有输出“0_1”、“1_1”等正确结果?
- 如果在我修改的代码中使用第二个循环,如何生成正确的结果?因为在我的真实情况下,max DegreeOfParallelism 是一个很大的数字。我无法将任务列表一一添加为MSDN example. 我以为我必须使用for循环。
【问题讨论】:
-
"maxDegreeOfParallelism 是一个很大的数字" 什么情况下需要您将并发线程的数量“限制”为一个很大的数字。我不是专家,但如果这个数字高于底层硬件/虚拟机可以同时运行的最大线程数,那么它肯定不会做任何事情。
标签: c# .net-4.0 task-parallel-library .net-4.5