2012-04-05 3 views
-2

J'essaie d'utiliser le TPL. Ne devrait-il pas fonctionner normalement, alors que tout ce que je définis dans mon corps d'action est complètement séparé? Cela ne semble pas être le cas. Quelqu'un peut-il me diriger dans la bonne direction. Fondamentalement, tout ce que je veux faire est d'exécuter une méthode plusieurs fois. Cette méthode crée toujours une instance d'un objet qui a une méthode d'exécution qui sera exécutée.C# TPL - Isolé?

+0

Pas clair du tout ce que vous voulez. – Aliostad

+0

Vous devriez publier le code en question, avec les résultats réels, et quels sont les résultats attendus - et pourquoi vous pensez qu'ils ne devraient pas être différents. – vcsjones

+0

préparera un exemple simple. – user1313693

Répondre

1

Bien que vous n'ayez pas fourni de code, le débogage psychique suggère que vous avez trouvé l'une des principales caractéristiques de lambdas, à savoir: les fermetures. (ou par votre nouveau commentaire: synchronisation, ou plutôt son absence)

Tenir compte:

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

Les deux y et z se réfèrent à la même instance de x. Maintenant, ceci est un exemple trivial, mais considérer le cas avec une boucle for ou foreach:

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

Toutes les 10 tâches référencera la même variable i! En fait, ils recevront probablement tous la même valeur de i. C'est parce qu'ils sont toutes les fermetures autour de la même variable en mémoire.

Si vous les aimez être indépendants, ils auront besoin de variables indépendantes pour leurs fermetures:

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

Peut-être l'autre cas, vous avez rencontré, nouveau code sans, est sychronization des structures de données. À moins que vous utilisez un concurrent data structure, il n'y a pas de synchronisation de la boîte:

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)); 

En combinant les deux problèmes que nous avons discuté, vous pouvez voir les problèmes que vous INTRODUISE avec le code suivant semble correct?

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

merci, je comprends cela et dans mon cas c'est encore plus simple car je n'utilise pas de variable de boucle.
<- langue: C# -> for (int i = 0; i <10; i ++) { Task.Factory.StartNew ( () => { var personne = new Person() ; personne.LoadInfoFromFile(); personne.CheckAnything(); }); } – user1313693

+0

Désolé, j'ai des problèmes d'édition. Je vais le réparer. L'exemple ne devrait-il pas fonctionner complètement indépendamment? – user1313693

+0

Est-ce que 'LoadInfoFromFile' et' CheckAnything' sont mutuellement exclusifs? Cela devrait être très proche de ce que vous avez. variations mineures pour la brièveté sont OK. Mais avec le filetage, il est souvent difficile de connaître tous les problèmes sans votre code exact. – user7116