2016-06-03 3 views
0

Ich versuche zu verstehen, wie ich den .NET 4.5 TPL besser nutzen kann. Traditionell verwaltete ich die Threads auf die alte Art und Weise, indem ich die Threads direkt anstellte und verwaltete.Asynchrone Tasks führt nur einen letzten Task in der Liste aus

ich ein dummes Programm erstellt haben die TPL jedoch zu erkunden, nur der Code die letzte der Aufgaben zu meiner Aufgabenliste hinzugefügt auszuführen scheint - ich kann nicht feststellen, warum:

class Program { 
    static void Main(string[] args) { 

     var a = new A(); 
     var b = new B(); 

     var tasks = new List<Task<string>>(); 
     for (int j = 33; j < 64; j++) { 
      tasks.Add(Task.Run(() => a.Go(j, 20)).ContinueWith((i) => b.Do(i))); 
     } 
     var finalTask = Task.Factory.ContinueWhenAll(tasks.ToArray(), r => { 
      foreach (var t in r) 
       Console.Write(t.Result); 
     }); 

     finalTask.Wait(); 

     Console.WriteLine("Finished."); 
     Console.ReadLine(); 

    } 
} 

public class A { 
    public int Go(int chr, int loops) { 
     for (int i = 0; i < loops; i++) { 
      Thread.Sleep(10); 
      Console.Write((char)chr); 
     } 
     return loops; 
    } 
} 

public class B { 
    public string Do(Task<int> value) { 
     string s = ""; 
     for (int i = 0; i < value.Result; i++) { 
      s = s + "a"; 
     } 
     return s; 
    } 
} 

Irgendwelche Ideen, warum die andere Threads werden nicht ausgeführt?

+0

Ich hasse es, dass ich eine große Antwort haben, die viel mehr als nur die Erfassung Problem behebt und ich kann nicht posten, weil die verdammte Frage beim Schreiben als Duplikat markiert wird. –

+0

Ich empfehle dringend, TAP zu betrachten, als Zeit mit TPL zu verschwenden. Es ist auf der gleichen Infrastruktur gebaut, aber glättet einen _lot_ der Ecken. Ich hatte eine Antwort, in der beschrieben wird, wie man mit TAP ein kleines Experiment durchführt, aber ich kann es nicht posten, weil es als Duplikat markiert wurde. –

Antwort

2

Sie haben die Laufvariable j innerhalb des Verschlusses Kontext zu erfassen:

for (int j = 33; j < 64; j++) { 
     var num = j; 
     tasks.Add(Task.Run(() => a.Go(num, 20)).ContinueWith((i) => b.Do(i))); 
    } 

Siehe auch Captured variable in a loop in C#

Verwandte Themen