Après une phase de test de mon planificateur de tâches, j'ai rencontré une impasse à peu près aléatoire. Je veux demander de l'aide, surtout je veux savoir si mon approche peut aboutir à une impasse ou si le problème est ailleurs.
Avant de commencer, je dirai que l'application est un jeu en plein écran. (au cas où cela pourrait influencer quelque chose)
Je vais expliquer en mots comment le système fonctionne.Impasse, quelques questions
Le Planificateur de tâches
1) L'annexe 2 par tâches CPU au début de chaque trame. (en programmant je veux dire en réglant le WaitHandle privé de la tâche à définir permettant à la tâche de faire un peu de travail)
Voici un court code qui résume ce que le système fait avec chacune des deux tâches. Une fois que toutes les deux tâches sont planifiées, elles sont initialisées en définissant le WaitHandle privé.
2) Attendez que toutes les tâches soient terminées. L'attente est effectuée en attendant que le WaitHandle interne indique que chaque tâche doit être signalée. (WaitOne() sur chaque tâche)
Voici le code de l'attente:
if (Attese.Length > 0)
{
TmpIsSucceded = false;
for (int i = 0; i < Attese.Length; i++)
{
WaitHandle actual = Attese[i].Wait;
do
{
TmpIsSucceded = actual.WaitOne(150);
if (!TmpIsSucceded)
EnginesManager.ProcessMessages();
} while (!TmpIsSucceded);
}
}
La tâche
1) est jamais fermé jusqu'à la fin du jeu.
2) A 2 WaitHandle interne. Un privé qui raconte la tâche quand il y a du travail pour lui. Un interne qui est signalé lorsque la tâche a terminé son travail. (celui attendu par le planificateur de tâches)
3) Lorsque la tâche est terminée, lancez elle-même une autre tâche disponible dans une file d'attente synchronisée (par lock()) du planificateur de tâches (de la même manière en définissant le waithandle privé de cette tâche).
c'est la boucle principale de la tâche:
private void CoreThread()
{
while (_active)
{
PrivateLock.WaitOne(-1, false);
while (Scheduled > 0)
{
if (OnThreadExecute != null)
OnThreadExecute(this, null);
Scheduled--;
if (Scheduled == 0)
{
PrivateLock.Reset();
if (OnThreadEnd != null)
OnThreadEnd(this, null);
InternalLock.Set();
}
}
}
}
InternalLock et PrivateLock sont les deux waitHandles. Veuillez noter que le waithandle InternalLock est uniquement défini dans ce code. Il n'y a AUCUN AUTRE ENDROIT où InternalLock ou PrivateLock sont installés. (sauf pour le code que j'ai posté)
Lorsque le blocage se produit, le planificateur de tâches attend que toutes les tâches soient terminées, mais l'une des tâches ne définit jamais le waithandle InternalLock. La tâche "bloquée" est arrêtée au "PrivateLock.WaitOne (-1, false);" ligne quand l'impasse se produit.
Quelqu'un at-il une idée de cette impasse?
Edit:
internal void StartSchedule()
{
for (int i = 0; i < Tasks.Length; i++)
{
if (Tasks[i].Schedule())
QTasks.Enqueue(Tasks[i]);
}
StartThreadAvailable();
}
private void StartThreadAvailable()
{
TempExecList.Clear();
for (int i = 0; i < NThread; i++)
{
if (QTasks.Count > 0)
TempExecList.Add(QTasks.Dequeue());
}
Int32 count = TempExecList.Count;
for (int i = 0; i < count; i++)
TempExecList[i].StartThread();
}
internal void StartThread()
{
PrivateLock.Set();
}
est ici le code où l'ensemble() de la poignée privée est appelée comme demandé. Schedule() renvoie toujours vrai dans ce cas.
(Il ajouter seulement 1 à la variable prévue de la tâche et remettre le InternalLock)
EDIT 2:
Voici le code des 2 classes comme demandé:
http://pastebin.com/m225f839e (GameTask)
http://pastebin.com/m389629cd (TaskScheduler)
Veuillez montrer le code qui contient 'PrivateLock.Set() ' –
Ajout du code demandé – feal87
Comment avez-vous déclaré les handles d'attente? pouvez-vous poster un échantillon de compilation complet? –