J'ai invoqué BeginInvoke sur 10 délégués dans une boucle. Au lieu d'utiliser 10 threads, le threadpool n'utilise que deux/trois threads pour exécuter les délégués. Est-ce que quelqu'un peut expliquer la raison de cela? L'exécution du délégué prend seulement quelques ms (moins de 10ms).
Quand j'ai enregistré les paramètres du threadpool avant d'invoquer BeginInvoke, cela indiquait que Min Threads = 2, Max Threads = 500, Threads disponibles = 498.
J'ai rencontré le problème lorsque j'ai invoqué le code C++ géré suivant.
void EventHelper::FireAndForget(Delegate^ d, ... array^ args)
{
try
{
if (d != nullptr)
{
array^ delegates = d->GetInvocationList();
String^ message1 = String::Format("Nombre d'éléments dans l'événement {0}",delegates.Length);
Log(LogMessageType::Information,"EventHelper.FireAndForget", message1);
// Parcours de la liste des méthodes de délégué.
for each(Delegate^ delegateMethod in delegates)
{
try
{
int minworkerThreads,maxworkerThreads,availworkerThreads, completionPortThreads;
ThreadPool::GetMinThreads(minworkerThreads, completionPortThreads);
ThreadPool::GetMaxThreads(maxworkerThreads, completionPortThreads);
ThreadPool::GetAvailableThreads(availworkerThreads, completionPortThreads);
String^ message = String::Format("Méthode FireAndForget {0}#{1} MinThreads - {2}, MaxThreads - {3} Threads disponibles - {4}",
delegateMethod->Method->DeclaringType, delegateMethod->Method->Name, minworkerThreads, maxworkerThreads, availworkerThreads);
Log(LogMessageType::Information,"EventHelper.FireAndForget", message);
DynamicInvokeAsyncProc^ evtDelegate = gcnew DynamicInvokeAsyncProc(this, &EventHelper::OnTriggerEvent);
evtDelegate->BeginInvoke(delegateMethod, args, _dynamicAsyncResult, nullptr); //FIX_DEC_09 Handle Leak
}
catch (Exception^ ex)
{
String^ message = String::Format("{0} : L'appel asynchrone dynamique de '{1}.{2}' a échoué", _id,
delegateMethod->Method->DeclaringType, d->Method->Name);
Log(LogMessageType::Information,"EventHelper.FireAndForget", message);
}
}
}
else
{
}
}
catch (Exception^ e)
{
Log(LogMessageType::Error, "EventHelper.FireAndForget", e->ToString());
}
}
Ceci est la méthode donnée dans le délégué
void EventHelper::OnTriggerEvent(Delegate^ delegateMethod, array^ args)
{
try
{
int minworkerThreads,maxworkerThreads,availworkerThreads, completionPortThreads;
ThreadPool::GetMinThreads(minworkerThreads, completionPortThreads);
ThreadPool::GetMaxThreads(maxworkerThreads, completionPortThreads);
ThreadPool::GetAvailableThreads(availworkerThreads, completionPortThreads);
String^ message = String::Format("Méthode OnTriggerEvent {0}#{1} MinThreads - {2}, MaxThreads - {3} Threads disponibles - {4}",
delegateMethod->Method->DeclaringType, delegateMethod->Method->Name, minworkerThreads, maxworkerThreads, availworkerThreads);
Log(LogMessageType::Information,"EventHelper::OnTriggerEvent", message);
message = String::Format("Avant d'invoquer la méthode {0}#{1}",
delegateMethod->Method->DeclaringType, delegateMethod->Method->Name);
Log(LogMessageType::Information,"EventHelper::OnTriggerEvent", message);
// Invoque dynamiquement (liaison tardive) la méthode représentée par le délégué actuel.
delegateMethod->DynamicInvoke(args);
message = String::Format("Après avoir invoqué la méthode {0}#{1}",
delegateMethod->Method->DeclaringType, delegateMethod->Method->Name);
Log(LogMessageType::Information,"EventHelper::OnTriggerEvent", message);
}
catch (Exception^ ex)
{
Log(LogMessageType::Error, "EventHelper.OnTriggerEvent", ex->ToString());
}
}