Run multiply instances of the same method simultaneously in c# without data loss?

与世无争的帅哥 提交于 2019-12-08 06:46:21

问题


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.


回答1:


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
    }
  }
}



回答2:


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



来源:https://stackoverflow.com/questions/15204198/run-multiply-instances-of-the-same-method-simultaneously-in-c-sharp-without-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!