C# 在同一对象上操作的多个任务

C# 在同一对象上操作的多个任务,c#,task-parallel-library,C#,Task Parallel Library,我刚刚用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++) {

我刚刚用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;
}

在我使用任务之前,生成任务大约需要4-5秒。在我像这样实现这个方法之后,如果我通过10-20个任务,生成时间将降低到1,8-2,2秒,但是方法返回的
List
中有
numotask
个元素,因此在这种情况下,返回10个数字的
List
。可能是我写错了什么。这里可能有什么问题。或者可能有另一种解决方法。我只想在同一个列表中添加数字,这样生成时间至少会快两倍。提前感谢

您将添加到以下循环中的列表中,该循环仅运行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;inums.Add(Rand.Nex());//Rand是一个ThreadLocal
}
你可以这样做

for (int i = 0; i < numOfTasks; i++)
    {
        tasks[i] = new Task(() => nums.Add(Rand.Nex()));
    }
for(int i=0;inums.Add(Rand.Nex());
}

正如Stephen所解释的,您只创建了10个任务


另外,我认为泛型列表上的
Add
操作不是线程安全的。您应该使用锁定机制,或者,如果您的目标是framework 4或更高版本,则在所有不运行任务时使用。

;它只是(异步)等待它们完成。你的代码只创建了10个任务,所以你只能得到10个数字。另外,正如@Mauro指出的,
List.Add
不是线程安全的

如果要执行并行计算,请使用
并行
或并行LINQ,而不是
异步

static List<int> GenerateList(int size, int numOfTasks)
{
    return Enumerable.Range(0, size)
        .AsParallel()
        .WithDegreeOfParallelism(numOfTasks)
        .Select(_ => Rand.Value.Next())
        .ToList();
}
静态列表生成器列表(int size,int numotasks)
{
返回可枚举范围(0,大小)
.天冬酰胺()
.具有平行度(numOfTasks)
.Select(=>Rand.Value.Next())
.ToList();
}

我想做的是假设10个任务将在几秒钟内将数字添加到列表并运行它们任务我可以运行任务数组而不在循环中分别运行它们吗?这不起作用,它会创建未启动的
任务,然后再也不会启动它们。即使你这样做了,你也只能开始每个
任务一次。@svick-我知道。。我只是告诉提问者如何在不启动任务的情况下完成任务1。那么,你为什么不这么说?你的答案文本没有这样说。2.这是如何回答这个问题的?我在问题中没有看到任何代码会关闭循环变量。
static List<int> GenerateList(int size, int numOfTasks)
{
    return Enumerable.Range(0, size)
        .AsParallel()
        .WithDegreeOfParallelism(numOfTasks)
        .Select(_ => Rand.Value.Next())
        .ToList();
}