所以,我只是在c#中做了一些任务类的实验,然后发生了下面的事情。
下面是我调用的方法
static async Task<List<int>> GenerateList(long size, int numOfTasks)
{
var nums = new List<int>();
Task[] tasks = new Task[numOfTasks];
for (int i = 0; i < numOfTasks; i++)
{
tasks[i] = Task.Run(() => nums.Add(Rand.Nex())); // Rand is a ThreadLocal<Random>
}
for (long i = 0; i < size; i += numOfTasks)
{
await Task.WhenAll(tasks);
}
return nums;
}我这样叫这个方法
var nums = GenerateList(100000000, 10).Result;在我使用任务之前,生成任务需要4到5秒。在像这样实现这个方法之后,如果我通过10-20个任务,生成的时间就会降低到1,8-2,2秒,但是这个方法返回的是List,其中包含numOfTask数,因此在这种情况下,返回10个数字的List。也许我写错了什么东西。这里有什么问题。或者可能有另一种解决办法。我想要的是在同一个列表中添加数字,这样生成时间至少要快两倍。提前谢谢
发布于 2014-01-23 12:43:50
WhenAll不运行这些任务;它只是(异步地)等待它们完成。您的代码只创建10个任务,这就是为什么您只得到10个数字的原因。此外,正如@Mauro所指出的,List<T>.Add不是线程安全。
如果您想进行并行计算,那么使用Parallel或并行LINQ,而不是使用async
static List<int> GenerateList(int size, int numOfTasks)
{
return Enumerable.Range(0, size)
.AsParallel()
.WithDegreeOfParallelism(numOfTasks)
.Select(_ => Rand.Value.Next())
.ToList();
}发布于 2014-01-23 08:59:57
正如Stephen所解释的,您只创建了10个任务。
另外,我认为泛型列表上的Add操作不是线程安全的。您应该使用锁定机制,或者,如果是针对框架4或更高版本,则使用线程安全集合。
发布于 2014-01-23 08:57:11
添加到下面循环中的列表中,该循环只运行10次
for (int i = 0; i < numOfTasks; i++)
{
tasks[i] = Task.Run(() => nums.Add(Rand.Nex())); // Rand is a ThreadLocal<Random>
}你可以代替
for (int i = 0; i < numOfTasks; i++)
{
tasks[i] = new Task(() => nums.Add(Rand.Nex()));
}https://stackoverflow.com/questions/21303330
复制相似问题