Dla Loop wynik przepełnienia z Task.Run lub Task.Start

Dla Loop wynik przepełnienia z Task.Run lub Task.Start

Jest to prawdopodobnie spowodowane problemem z zamknięciem.

Spróbuj tego:

 for (int i = 0; i < 4; i++)
 {
      //start task with current connection
      int index = i;
      tasks[index] = Task<byte[]>.Run(() => GetData(index, plcPool[index]));
 }

Prawdopodobnie dzieje się tak, że kiedy ostatni wątek zaczyna działać, pętla już się zwiększyła i do 4 i to jest wartość przekazywana do GetData() . Przechwytywanie wartości i do osobnej zmiennej index a użycie tego zamiast tego powinno rozwiązać ten problem.

Na przykład, jeśli wypróbujesz ten kod:

public static void Main()
{
    Console.WriteLine("Starting.");

    for (int i = 0; i < 4; ++i)
        Task.Run(() => Console.WriteLine(i));

    Console.WriteLine("Finished. Press <ENTER> to exit.");
    Console.ReadLine();
}

często daje taki rodzaj danych wyjściowych:

Starting.
Finished. Press <ENTER> to exit.
4
4
4
4

Zmień ten kod na:

public static void Main()
{
    Console.WriteLine("Starting.");

    for (int i = 0; i < 4; ++i)
    {
        int j = i;
        Task.Run(() => Console.WriteLine(j));
    }

    Console.WriteLine("Finished. Press <ENTER> to exit.");
    Console.ReadLine();
}

i dostajesz coś takiego

Starting.
Finished. Press <ENTER> to exit.
0
1
3
2

Zwróć uwagę, że NADAL NIE KONIECZNIE W ZAMÓWIENIU! Zobaczysz wydrukowane wszystkie prawidłowe wartości, ale w nieokreślonej kolejności. Wielowątkowość jest podstępna!