Je suis en train d'essayer de mieux comprendre la Async et le Parallèle options que j'ai dans le C#. Dans les extraits ci-dessous, j'ai inclus les 5 approches que je viens dans la plupart des. Mais je ne suis pas sûr de choisir - ou, mieux encore, quels sont les critères à considérer lors du choix:
Méthode 1: Tâche
(voir http://msdn.microsoft.com/en-us/library/dd321439.aspx)
L'appel de StartNew est fonctionnellement équivalent à la création d'une Tâche à l'aide de l'un de ses constructeurs et puis l'appel de Commencer à planifier pour l'exécution. Cependant, à moins que la création et la planification doivent être séparés, StartNew est l'approche recommandée pour tant de simplicité et de performance.
TaskFactory de StartNew méthode devrait être le mécanisme privilégié pour créer et planifier des tâches de calcul, mais pour les scénarios où la création et de la programmation doivent être séparés, les constructeurs peuvent être utilisés, et le Début de la tâche de la méthode peut alors être utilisé pour planifier la tâche de l'exécution à une date ultérieure.
// using System.Threading.Tasks.Task.Factory
void Do_1()
{
var _List = GetList();
_List.ForEach(i => Task.Factory.StartNew(_ => { DoSomething(i); }));
}
Méthode 2: QueueUserWorkItem
(voir http://msdn.microsoft.com/en-us/library/system.threading.threadpool.getmaxthreads.aspx)
Vous pouvez faire la queue comme beaucoup de pool de threads de demandes de la mémoire système. Si il y a plus de demandes que le pool de threads, les demandes supplémentaires restent en file d'attente jusqu'à ce que le pool de threads sont disponibles.
Vous pouvez placer des données requises par la file d'attente de la méthode dans les champs d'instance de la classe dans laquelle la méthode est définie, ou vous pouvez utiliser le QueueUserWorkItem(WaitCallback, Objet) surcharge qui accepte un objet contenant les données nécessaires.
// using System.Threading.ThreadPool
void Do_2()
{
var _List = GetList();
var _Action = new WaitCallback((o) => { DoSomething(o); });
_List.ForEach(x => ThreadPool.QueueUserWorkItem(_Action));
}
Méthode 3: Parallèle.Foreach
(voir: http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx)
La classe Parallèle fournit une bibliothèque de base de données parallèle de remplacement pour les opérations courantes telles que les boucles for, pour chacune des boucles, et l'exécution d'un ensemble d'instructions.
Le corps délégué est appelée une fois pour chaque élément de la source énumérable. Il est fourni avec l'élément courant en tant que paramètre.
// using System.Threading.Tasks.Parallel
void Do_3()
{
var _List = GetList();
var _Action = new Action<object>((o) => { DoSomething(o); });
Parallel.ForEach(_List, _Action);
}
Méthode 4: IAsync.BeginInvoke
(voir: http://msdn.microsoft.com/en-us/library/cc190824.aspx)
BeginInvoke est asynchrone; par conséquent, le contrôle retourne immédiatement à l'objet appelant après, il est appelé.
// using IAsync.BeginInvoke()
void Do_4()
{
var _List = GetList();
var _Action = new Action<object>((o) => { DoSomething(o); });
_List.ForEach(x => _Action.BeginInvoke(x, null, null));
}
Méthode 5: BackgroundWorker
(voir: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx)
De mettre en place une opération en arrière-plan, ajouter un gestionnaire d'événements pour l'événement DoWork. Appelez votre temps de fonctionnement de ce gestionnaire d'événement. Pour démarrer l'opération, appelez RunWorkerAsync. Pour recevoir les notifications de mises à jour du progrès, de la poignée de l'événement ProgressChanged. Pour recevoir une notification lorsque l'opération est terminée, la poignée de la RunWorkerCompleted événement.
// using System.ComponentModel.BackgroundWorker
void Do_5()
{
var _List = GetList();
using (BackgroundWorker _Worker = new BackgroundWorker())
{
_Worker.DoWork += (s, arg) =>
{
arg.Result = arg.Argument;
DoSomething(arg.Argument);
};
_Worker.RunWorkerCompleted += (s, arg) =>
{
_List.Remove(arg.Result);
if (_List.Any())
_Worker.RunWorkerAsync(_List[0]);
};
if (_List.Any())
_Worker.RunWorkerAsync(_List[0]);
}
}
Je suppose que le critère évident serait:
- Est meilleure que les autres pour la performance?
- Est meilleure que les autres pour le traitement des erreurs?
- Est mieux que l'autre pour le suivi/feedback?
Mais, comment voulez - vouschoisir? Merci d'avance pour vos idées.