【问题标题】:Several Tasks manipulating on same Object操作同一对象的多个任务
【发布时间】:2014-01-23 23:06:50
【问题描述】:

所以我只是在 c# 中对 Task 类进行了一些实验,然后发生了以下事情。

这是我调用的方法

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 编号其中的元素,因此在这种情况下,返回十个数字的List。可能是我写错了。这里可能是什么问题。或者可能有另一种解决方案。我希望它有很多任务可以在同一个列表中添加数字,因此生成时间至少会快两倍。提前致谢

【问题讨论】:

    标签: c# task-parallel-library


    【解决方案1】:

    WhenAll 不运行任务;它只是(异步)等待它们完成。您的代码只创建了 10 个任务,这就是为什么您只得到 10 个数字的原因。此外,正如@Mauro 指出的那样,List&lt;T&gt;.Add 不是线程安全的。

    如果要进行并行计算,请使用Parallel 或Parallel LINQ,而不是async

    static List<int> GenerateList(int size, int numOfTasks)
    {
        return Enumerable.Range(0, size)
            .AsParallel()
            .WithDegreeOfParallelism(numOfTasks)
            .Select(_ => Rand.Value.Next())
            .ToList();
    }
    

    【讨论】:

      【解决方案2】:

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

      另外,我相信泛型列表上的Add 操作不是线程安全的。您应该使用锁定机制,或者,如果您的目标是框架 4 或更高版本,请使用 thread-safe collections

      【讨论】:

      • 我在问题中看不到任何会关闭循环变量的代码。
      【解决方案3】:

      您将在以下循环中添加到列表中,该循环仅运行 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()));
          }
      

      【讨论】:

      • 我想要做的是假设有 10 个任务将添加数字以列出并在秒任务中运行它们
      • 我可以运行任务数组而不在循环中单独运行它们吗?
      • 这不起作用,它会创建未启动的Tasks,然后永远不会启动它们。即使你这样做了,你也只能启动每个Task 一次。
      • @svick - 我知道.. 我只是告诉提问者如何在不启动任务的情况下完成任务
      • 1.那么,你为什么不这么说呢?你的答案的文字没有这么说。 2. 这如何回答这个问题?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 2013-02-19
      • 1970-01-01
      相关资源
      最近更新 更多