Run multiply instances of the same method simultan

2019-06-07 22:41发布

I really don't understand Tasks and Threads well. I have a method inside three levels of nested for that I want to run multiple times in different threads/tasks, but the variables I pass to the method go crazy, let me explain with some code:

List<int> numbers=new List<int>();
for(int a=0;a<=70;a++)
{
  for(int b=0;b<=6;b++)
  {
    for(int c=0;b<=10;c++)
    {
        Task.Factory.StartNew(()=>MyMethod(numbers,a,b,c));
    }
  }
}
private static bool MyMethod(List<int> nums,int a,int b,int c)
{
    //Really a lot of stuff here
}

This is the nest, myMethod really does a lot of things, like calculating the factorial of some numbers, writing into different documents and matching responses with a list of combinations and calling other little methods, it has also some return value (booleans), but I don't care about them at the moment. The problem is that no task reach an end, it's like everytime the nest call the method it refreshes itself, removing previous instances. It also give an error, "try to divide for 0", with values OVER the ones delimited by FORs, for example a=71, b=7, c=11 and all variables empty(that's why divided by zero). I really don't know how to solve it.

2条回答
相关推荐>>
2楼-- · 2019-06-07 23:13

Check your for statements. b and c are never incremented.

You then have a closure over the loop variables which is likely to be the cause of other problems.

Captured variable in a loop in C#

Why is it bad to use an iteration variable in a lambda expression

查看更多
劳资没心,怎么记你
3楼-- · 2019-06-07 23:22

The problem is, that you are using a variable that has been or will be modifed outside your closure/lambda. You should get a warning, saying "Access to modified closure".

You can fix it by putting your loop variables into locals first and use those:

namespace ConsoleApplication9
{
  using System.Collections.Generic;
  using System.Threading.Tasks;

  class Program
  {
    static void Main()
    {
      var numbers = new List<int>();

      for(int a=0;a<=70;a++)
      {
        for(int b=0;b<=6;b++)
        {
          for(int c=0;c<=10;c++)
          {
            var unmodifiedA = a;
            var unmodifiedB = b;
            var unmodifiedC = c;

            Task.Factory.StartNew(() => MyMethod(numbers, unmodifiedA, unmodifiedB, unmodifiedC));
          }
        }
      }
    }

    private static void MyMethod(List<int> nums, int a, int b, int c)
    {
      //Really a lot of stuffs here
    }
  }
}
查看更多
登录 后发表回答