2012-04-05 14 views
-2

Ich versuche, die TPL zu verwenden. Sollte es nicht normal so funktionieren, dass alles, was ich in meinem Action Body definiere, komplett getrennt ist? Es scheint nicht der Fall zu sein. Kann mir jemand in die richtige Richtung weisen? Grundsätzlich möchte ich nur eine Methode mehrmals ausführen. Diese Methode erstellt immer eine Instanz eines Objekts mit einer Ausführungsmethode, die ausgeführt wird.C# TPL - Isoliert?

+0

Nicht klar, was Sie wollen. – Aliostad

+0

Sie sollten den fraglichen Code zusammen mit den tatsächlichen Ergebnissen und Ihren erwarteten Ergebnissen veröffentlichen - und warum Sie denken, dass sie nicht anders sein sollten. – vcsjones

+0

wird ein einfaches Beispiel vorbereiten. – user1313693

Antwort

1

Während Sie keinen Code zur Verfügung gestellt haben, schlägt psychisches Debugging vor, dass Sie eine der Hauptfunktionen von lambdas gefunden haben, nämlich: closures. (oder pro Ihren Kommentar: Synchronisation, oder vielmehr der Mangel davon)

Bedenken Sie:

int x = 0; 
Action y =() => Console.WriteLine("{0}", x++); 
Action z =() => Console.WriteLine("{0}", --x); 

Sowohl y und z auf derselben Instanz von x beziehen. Nun, dies ist ein triviales Beispiel, aber betrachten wir den Fall mit einer for Schleife oder einem foreach:

for (int i = 0; i < 10; ++i) 
{ 
    Task.Factory.StartNew(() => Console.WriteLine("{0}", i)); 
} 

Alle 10 Aufgaben die gleiche Variable i Referenz! In der Tat werden sie wahrscheinlich alle den gleichen Wert von i erhalten. Dies ist, weil sie alle Verschlüsse um die gleiche Variable im Speicher sind.

Wenn Sie sie unabhängig sein möchte, werden sie unabhängige Variablen müssen für ihre Verschlüsse:

foreach (var datum in data) 
{ 
    // Because myDatum is local to *each* loop iteration, 
    // each Task will receive its own variable. The same 
    // strategy applies to for-loops. 
    var myDatum = datum; 
    Task.Factory.StartNew(() => Frob(myDatum)); 
} 

Vielleicht ist der andere Fall, dass Sie den Weg laufen haben, wieder sans-Code, Sychronisation von Datenstrukturen ist. Sofern Sie eine concurrent data structure verwenden, gibt es keine Synchronisation aus der Box:

var bad = new List<int>();   // No implicit thread safety 
var good = new ConcurrentBag<int>(); // Thread safe access 

Parallel.For(0, 1000, x => bad.Add(x)); 
Parallel.For(0, 1000, x => good.Add(x)); 

Die Kombination der beiden Probleme, die wir besprochen haben, können Sie die Probleme sehen Sie in der folgenden scheinbar korrekten Code ausführen würde?

var counts = new Dictionary<int, int>(); 
for (int i = 0; i < 1000; ++i) 
{ 
    // How many ways can this fail? One should be enough. 
    Task.Factory.StartNew(
     () => 
     { 
      counts[i] = GetCounts(i); 
     }); 
} 
+0

danke, ich verstehe das und in meinem Fall ist es noch einfacher, da ich keine Loop-Variable verwende.
for (int i = 0; i <10; i ++) { Task.Factory.StartNew ( () => { var person = new Person() ; person.LoadInfoFromFile(); person.CheckAnything(); }); } – user1313693

+0

Entschuldigung, ich habe Bearbeitungsprobleme. Wird es reparieren. Sollte das Beispiel nicht völlig unabhängig funktionieren? – user1313693

+0

Schließen sich "LoadInfoFromFile" und "CheckAnything" gegenseitig aus? Es sollte sehr nah an dem sein, was Sie haben; kleinere Variationen für die Kürze sind Ok. Aber mit Threading ist es oft schwierig, jedes Problem ohne Ihren genauen Code zu kennen. – user7116