Implémentation actuelle: Attend que les valeurs parallelCount
soient collectées, utilise ThreadPool
pour traiter les valeurs, attende que tous les threads soient terminés, recollecte un autre jeu de valeurs, etc.C# - Renvoie les données du thread ThreadPool au thread principal
code:
private static int parallelCount = 5;
private int taskIndex;
private object[] paramObjects;
// Each ThreadPool thread should access only one item of the array,
// release object when done, to be used by another thread
private object[] reusableObjects = new object[parallelCount];
private void MultiThreadedGenerate(object paramObject)
{
paramObjects[taskIndex] = paramObject;
taskIndex++;
if (taskIndex == parallelCount)
{
MultiThreadedGenerate();
// Reset
taskIndex = 0;
}
}
/*
* Called when 'paramObjects' array gets filled
*/
private void MultiThreadedGenerate()
{
int remainingToGenerate = paramObjects.Count;
resetEvent.Reset();
for (int i = 0; i < paramObjects.Count; i++)
{
ThreadPool.QueueUserWorkItem(delegate(object obj)
{
try
{
int currentIndex = (int) obj;
Generate(currentIndex, paramObjects[currentIndex], reusableObjects[currentIndex]);
}
finally
{
if (Interlocked.Decrement(ref remainingToGenerate) == 0)
{
resetEvent.Set();
}
}
}, i);
}
resetEvent.WaitOne();
}
J'ai vu des améliorations de performances significatives avec cette approche, mais il y a un certain nombre de questions à considérer:
[1] valeurs enCollectionneret la synchronisation à l'aide de resetEvent
peut être évitée car il n'y a pas de dépendance entre les threads (ou l'ensemble actuel de valeurs avec l'ensemble de valeurs suivant). Je fais seulement ceci pour gérer l'accès à reusableObjects
(quand un ensemble paramObjects
est fait traitement, je sais que tous les objets dans réutilisableObjects sont libres, ainsi taskIndex
est remis à zéro et chaque nouvelle tâche du prochain ensemble de valeurs aura son unique 'réutilisableObj ' travailler avec).
[2] Il n'y a pas de réelle connexion entre la taille de reusableObjects
et le nombre de threads que le ThreadPool
utilise. Je peux initialiser reusableObjects
pour avoir 10 objets, et dire qu'en raison de certaines limitations, ThreadPool peut exécuter seulement 3 threads pour ma méthode MultiThreadedGenerate()
, puis je gaspille de la mémoire.
Alors en se débarrassant de paramObjects
, comment le code ci-dessus être affiné d'une manière qui dès qu'un thread termine son travail, ce thread retourne son taskIndex
(ou reusableObj
) il utilisé et n'a plus besoin de façon à devient disponible à la prochaine valeur. En outre, le code devrait créer un reUsableObject
et l'ajouter à une collection seulement quand il y a une demande pour cela. Utiliser une file d'attente ici est-il une bonne idée?
Merci.
Dans quelle version de .Net êtes-vous? –
J'utilise .NET 3.5 – alhazen