c#中的并行与任务
本文关键字:任务 并行 | 更新日期: 2023-09-27 18:04:35
我有一个方法,它需要进行多个服务调用并合并结果。我试着用Task来做这个,结果不正确,所以我做了下面两个测试。
使用任务List<Task<string>> tasks = new List<Task<string>>();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < 20; i++)
{
tasks.Add(Task.Factory.StartNew(() =>
{
long started = stopwatch.ElapsedMilliseconds;
Random wait = new Random();
int waited = wait.Next(500, 3000);
Thread.Sleep(waited);
return string.Format("Index #{0} started at {1}ms and waited {2}ms", i, started, waited);
}));
}
Task.WaitAll(tasks.ToArray());
foreach (Task<string> task in tasks)
{
Console.WriteLine(string.Format("[Task {0,2}] {1}", task.Id, task.Result));
}
使用并行Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int[] inputs = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
Parallel.ForEach(inputs, i =>
{
long started = stopwatch.ElapsedMilliseconds;
Random wait = new Random();
int waited = wait.Next(500, 3000);
Thread.Sleep(waited);
string result = string.Format("Task {0,2} started at {1} ms and waited {2} ms", i, started, waited);
Console.WriteLine(result);
});
stopwatch.Stop();
Console.WriteLine("Total time taken: " + stopwatch.ElapsedMilliseconds.ToString());
如下所示,任务索引一直被打印为20(尽管传递的是0到19)。而且,并行比任务花费更多的时间。下面是结果,显然我在任务中做错了什么,无法弄清楚是什么:(
任务输出
[Task 1] Index #20 started at 0ms and waited 875ms
[Task 2] Index #20 started at 0ms and waited 875ms
[Task 3] Index #20 started at 0ms and waited 875ms
[Task 4] Index #20 started at 0ms and waited 875ms
[Task 5] Index #20 started at 0ms and waited 875ms
[Task 6] Index #20 started at 0ms and waited 875ms
[Task 7] Index #20 started at 855ms and waited 1477ms
[Task 8] Index #20 started at 886ms and waited 1965ms
[Task 9] Index #20 started at 886ms and waited 1965ms
并行输出Task 6 started at 1046 ms and waited 636 ms
Task 11 started at 1561 ms and waited 758 ms
Task 0 started at 16 ms and waited 2891 ms
Task 5 started at 16 ms and waited 2891 ms
Task 15 started at 17 ms and waited 2891 ms
Task 1 started at 17 ms and waited 2891 ms
Task 10 started at 17 ms and waited 2891 ms
对于实际方法,我也有相同的经验,其中最后一项被多次返回,而不是单个结果。
如果你能给我指路就太好了。
注:输出是局部的。实际输出为20项
您需要对i
形成一个闭包。下面是最简单的方法:
for (int x = 0; x < 20; x++)
{
var i = x;
tasks.Add(...) // keep using `i` inside here & never `x`
}
当使用任务方法时,您在'i'上有一个闭包,这就是为什么所有任务id都显示为20(即。当任务实际执行时,所有20个任务都已被调度,因此当方法执行时I == 20)。
Parallel主要用于允许您扩展算法以使用机器上可用的CPU资源。如果问题不是CPU限制(即调用WebServices)并行不是正确的抽象。
所以在你的情况下,任务似乎是正确的选择。