2008-10-10 11 views
6

J'ai une application .NET qui traite environ 300 000 enregistrements dans une importation par lot, et cela prend quelques secondes par enregistrement, donc je voudrais paralléliser cela. Dans le code suivant, quelle est la différence entre ProcessWithAnsycDelegates() et ProcessWithThreadPool()?Utilisez des délégués asynchrones ou ThreadPool.QueueUserWorkItem pour un parallélisme massif?

public class ResultNotification 
{ public EventHandler event Success; 
    public EventHandler event Fail; 
    internal void Notify(bool sucess) {if (success) Success(); else Fail();} 
} 

public static class Processor 
{ public ResultNotification ProcessWithAnsycDelegates(Record record) 
    { var r = new ResultNotification(); 
     Func<Record,bool> processRecord=new RecordProcessor().ProcessRecord; 
     processRecord.BeginInvoke 
        (record 
         ,ar => result.Notify(processRecord.EndInvoke(ar)) 
         ,null); 
     return r;  
    } 

    public ResultNotification ProcessWithThreadPool(Record r) 
    { var r = new ResultNotification(); 
     var rp = new RecordProcessor(); 
     ThreadPool.QueueWorkUserItem(_=>result.Notify(rp.ProcessRecord(r))); 
     return r; 
    } 
} 

Répondre

6

Dans ce cas, pas beaucoup car ils utilisent tous les deux le pool de threads sous le capot. Je dirais que le QueueUserWorkItem() est plus facile à lire et à voir ce qui se passe par rapport à BeginInvoke.

Ce lien peut vous aider. Il s'agit d'une information plus ancienne, mais toujours applicable http://www.yoda.arachsys.com/csharp/threads/threadpool.shtml

+0

Quelles parties ne sont pas applicables? – bzlm

7

La réponse littérale à la question est que les deux utilisent le pool de threads, donc la différence n'est pas grande si la performance est la seule considération.

Si la question est vraiment d'obtenir les meilleures performances, alors il peut être utile de savoir que l'utilisation du pool de threads pose des problèmes. Ceux-ci comprennent:

  • contention de verrouillage sur la file d'attente
  • de changement de contexte excessif. Si vous avez 2 processeurs et une séquence d'éléments de travail, 25 threads n'aident pas vraiment. Il vaut mieux avoir 2 fils, un pour chaque CPU

Il pourrait être utile d'examiner la TPL et PLINQ:

Un exemple, ils donner du TPL utilisé est:

for (int i = 0; i < 100; i++) { 
    a[i] = a[i]*a[i]; 
} 

à:

Parallel.For(0, 100, delegate(int i) { 
    a[i] = a[i]*a[i]; 
});