Nous disposons d'une application C# multitâche très performante, quasiment en temps réel. Ces performances ont été obtenues principalement en implémentant le multitâche coopératif en interne avec un planificateur maison. Ce système est souvent appelé micro-threads. Dans ce système, toutes les tâches communiquent avec d'autres tâches via des files d'attente.
Le problème spécifique que nous rencontrons ne semble pouvoir être résolu que par des continuations de première classe, que le C# ne prend pas en charge.
Plus précisément, le problème se pose dans 2 cas traitant des files d'attente. Chaque fois qu'une tâche particulière effectue un travail avant de placer un élément dans une file d'attente. Que se passe-t-il si la file d'attente est pleine ?
À l'inverse, une autre tâche peut effectuer un travail et avoir ensuite besoin de retirer un élément d'une file d'attente. Et si cette file d'attente est vide ?
Nous avons résolu ce problème dans 90% des cas en liant les files d'attente aux tâches pour éviter que les tâches soient invoquées si l'une de leurs files d'attente sortantes est pleine ou si la file d'attente entrante est vide.
De plus, certaines tâches ont été converties en machines à états afin qu'elles puissent gérer si une file d'attente est pleine/vide et continuer sans attendre.
Le véritable problème se pose dans quelques cas limites où il n'est pas possible d'appliquer l'une ou l'autre de ces solutions. Dans ce cas, l'idée serait de sauvegarder l'état de la pile à ce moment-là et de passer à une autre tâche pour qu'elle puisse effectuer le travail, puis de relancer la tâche en attente dès qu'elle est en mesure de continuer.
Dans le passé, nous avons essayé de faire en sorte que la tâche en attente rappelle le planning (de manière récursive) pour permettre aux autres tâches de relancer la tâche en attente. Cependant, cela conduisait à trop de situations de "blocage".
Il y avait un exemple quelque part d'un hôte CLR personnalisé pour que les threads .NET fonctionnent réellement comme des "fibres", ce qui permet essentiellement de changer l'état de la pile entre les threads. Mais je n'arrive pas à trouver d'exemple de code pour cela. De plus, il semble qu'il faille une certaine complexité pour y parvenir.
Quelqu'un a-t-il d'autres idées créatives pour passer d'une tâche à l'autre efficacement et éviter les problèmes susmentionnés ?
Y a-t-il d'autres hôtes CLR qui offrent cela, commerciaux ou non ? Existe-t-il une bibliothèque native complémentaire qui puisse offrir une certaine forme de continuations pour C# ?