2012-04-25 1 views
3

J'ai ce morceau de code dans un thread secondaire:fois WaitForSingleObject trop rapide

DWORD result = WaitForSingleObject(myhandle,10000); 
if(result == WAIT_OBJECT_0){ 
    AfxMessageBox(_T(...)); 
} 
else if(result == WAIT_TIMEOUT){ 

    AfxMessageBox(_T("Timeout")); 
} 

Parfois, pas toujours, le délai d'attente sera appelé presque dès que le WaitForSingleObject est appelé (retard même pas 1s) .

Est-ce que je fais quelque chose de mal? Des suggestions pour des alternatives plus stables?


EDIT:

myhandle est créé dans un constructeur de classe:

myhandle = CreateEvent(NULL,FALSE,FALSE,_T("myhandle")); 

il s'appelé par une autre fonction:

SetEvent(myhandle); 

Le point est-il fonctionne quand Je fais le SetEvent, le problème est qu'il arrive parfois à expiration dès que le WaitForSingleObjec On l'appelle, même s'il faut attendre 10 secondes.

+0

Qu'attendez-vous? D'où vient ma poignée? – RedX

+0

Voir edit :) ... – Smash

+0

Avez-vous vérifié 'GetLastError()' avant et après l'attente? –

Répondre

0

m'a pris un moment mais le problème était en fait que le programme faisait parfois plusieurs appels à WaitForSingleObject. C'est donc un appel précédent qui expire.

La solution consiste à utiliser WaitForMultipleObjects et à définir un événement d'annulation dans le cas où il est connu que le premier événement ne sera pas défini, de sorte que le temporisateur est annulé avant d'être de nouveau appelé.

1

Avez-vous vraiment besoin d'un événement nommé? Généralement, cela n'est requis que pour le contrôle de concurrence entre processus.

Si vous avez plusieurs instances de cette classe, elles utiliseront toutes le même événement - voir le docs for CreateEvent pour appeler un objet nommé qui existe déjà.

Il se peut que tout ce que vous devez faire est de supprimer le nom ici. Cela permet à chaque instance de classe d'avoir son propre objet Event et le comportement devrait être plus prévisible.

+0

La classe dans laquelle l'événement est créé est un singleton. Il est défini à partir de la vue principale: 'Class :: instance() -> SetEvent()' dans laquelle le code est 'SetEvent (myhandle);' Je vais essayer ce que vous suggérez.CreateEvent (NULL, FALSE, FALSE, NULL) – Smash

+0

Oui, mais cela ne compte que si plusieurs appellent ce code. Exécutez-vous plus d'une instance du programme? –

0

WaitForSingleObject n'attendra pas pendant 10 secondes. Il attendra la première:

  1. La valeur du délai est écoulé
  2. L'événement est signalé
  3. La poignée devient invalide (fermé dans un autre thread)

Si l'événement est réglé Lorsque vous appelez WaitForSingleObject, la condition 2 est vraie depuis le début et WaitForSingleObject revient immédiatement.

Si vous voulez toujours attendre 10 secondes, vous devez utiliser le code comme ceci:

//Always wait 10 seconds 
Sleep(10000); 

//Test the event without waiting 
if(WaitForSingleObject(myhandle, 0) == WAIT_OBJECT_0) { 
    AfxMessageBox(_T("Event was set in the last 10 secondes")); 
} else { 
    AfxMessageBox(_T("Timeout")); 
}