Question

J'ai un code de transfert de fichiers haute performance que j'ai écrit en C # en utilisant le modèle de programmation Async (APM de) langue (par exemple, BeginRead / EndRead). Ce code lit un fichier à partir d'un disque local et l'écrit dans une prise.

Pour de meilleures performances sur le matériel moderne, il est important de garder plus d'une opération d'E / S en attente en vol lorsque cela est possible. Ainsi, je posterai plusieurs opérations de BeginRead sur le fichier, puis quand on finalise, j'appelle un BeginSend sur la prise, et quand je fais qui vient compléter une autre BeginRead sur le fichier. Les détails sont un peu plus compliqué que cela, mais au haut niveau qui est l'idée.

J'ai le travail de code basé APM, mais il est très difficile à suivre et a probablement des bugs subtils de concurrence. J'aimerais utiliser TPL pour cette place. Je me suis dit Task.Factory.FromAsync ferait à peu près, mais il y a un hic.

Toutes les E / S des échantillons que j'ai vu (plus particulièrement la classe StreamExtensions dans les extensions parallèles Extras) suppose un contrat de lecture suivie d'une écriture. Cela ne fonctionnera pas I façon besoin.

Je ne peux pas utiliser simplement quelque chose comme Parallel.ForEach ou l'extension Extras Task.Factory.Iterate parce que les tâches d'E / S async ne passent pas beaucoup de temps sur un thread de travail, donc parallèle commence juste une autre tâche, entraînant potentiellement des dizaines ou des centaines de en attente des opérations d'E / S; beaucoup trop! Vous pouvez contourner ce problème par Waiting vos tâches, mais qui provoque la création d'une poignée d'événement (un objet noyau), et une attente de blocage sur une poignée d'attente des tâches, qui ligote un thread de travail. Ma mise en œuvre sur la base APM évite à la fois de ces choses.

Je joue autour de différentes façons de maintenir les opérations de lecture / écriture multiples en vol, et je l'ai réussi à le faire en utilisant les continuations qui appellent une méthode qui crée une autre tâche, mais il se sent maladroit, et certainement doesn » t sentir comme idiomatiques TPL.

Quelqu'un d'autre aux prises avec un problème comme celui-ci avec le TPL? Toutes les suggestions?

Était-ce utile?

La solution

Si vous êtes inquiet au sujet trop de threads, vous pouvez juste ParallelOptions.MaxDegreeOfParallelism ensemble à un nombre acceptable dans votre appel à Parallel.ForEach.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top