Compartilhar via


Classe CEvent

Representa um evento, que é um objeto de sincronização que permite que um segmento para notificar outros que um evento ocorreu.

class CEvent : public CSyncObject

Membros

Construtores public

Nome

Descrição

CEvent::CEvent

Constrói um objeto de CEvent .

Métodos públicos

Nome

Descrição

CEvent::PulseEvent

Defina o evento para disponível (sinalizar), as versões que esperam segmentos, e define o evento para disponível (não não sinalizado).

CEvent::ResetEvent

Defina o evento para nonsignaled (não disponível).

CEvent::SetEvent

Defina o evento para disponível (sinalizar) e para versões todos os segmentos de espera.

CEvent::Unlock

Libera o objeto de evento.

Comentários

Os eventos são úteis quando um segmento deve saber quando executar a tarefa. Por exemplo, um segmento que copia dados em um arquivo arquivamento de dados deve ser notificado quando novos dados estão disponíveis. Usando um objeto de CEvent para notificar a cópia encadeamento de dados quando novos estão disponíveis, o segmento pode executar a tarefa o mais rápido possível.

Os objetos deCEvent têm dois tipos: manual e automático.

Um objeto automática de CEvent retorna automaticamente a um estado (não disponível) não sinalizado após pelo menos um segmento é liberado. Por padrão, um objeto de CEvent é automática a menos que você TRUE passar para o parâmetro de bManualReset durante a compilação.

Um objeto de CEvent manuais fica no estado definido por SetEvent ou por ResetEvent até que a outra função é chamada. Para criar um objeto manual de CEvent , TRUE passar para o parâmetro de bManualReset durante a compilação.

Para usar um objeto de CEvent , construir o objeto de CEvent quando for necessário. Especificar o nome do evento que você deseja aguardar no, e também especifica que o aplicativo deve possuir o inicialmente. Você pode acessar o evento quando o construtor retorna. Chame SetEvent para sinalizar (disponibiliza) o objeto de evento e chamar em desbloquear quando você terminar ao acessar o recurso controlado.

Um método alternativo para usar objetos de CEvent é adicionar uma variável do tipo CEvent como um membro de dados para a classe que você deseja controlar. Durante a compilação do objeto controlada, chamar o construtor do membro de dados de CEvent e especifica se o evento é sinalizado inicialmente, e também tipo de specifythe de objeto de evento que você deseja, o nome do evento (se será usado fora dos limites de processo), e todos os atributos de segurança você deseja.

Para acessar um recurso controlado por um objeto de CEvent de essa maneira, primeiro crie uma variável do tipo CSingleLock ou digite CMultiLock no método de acesso do recurso. Chame o método de Lock do objeto de bloqueio (por exemplo, CMultiLock::Lock). Em este ponto, o segmento acederá ao recurso espera, para que o recurso seja liberado e acederá, ou esperará o recurso a ser liberados, o tempo limite, e a falha obter acesso ao recurso. Em qualquer caso, o recurso foi acessado de uma maneira segura. Para liberar o recurso, chame SetEvent para sinalizar o objeto de evento em seguida, use o método de Unlock do objeto de bloqueio (por exemplo, CMultiLock::Unlock), ou deixe o bloqueio objeto a queda fora do escopo.

Para obter mais informações sobre como usar objetos de CEvent , consulte Multithread: como usar as classes de sincronização.

Exemplo

// The following demonstrates trivial usage of the CEvent class. 
// A CEvent object is created and passed as a parameter to another  
// thread.  The other thread will wait for the event to be signaled 
// and then exit

UINT __cdecl MyThreadProc(LPVOID lpParameter)
{
   CEvent* pEvent = (CEvent*)(lpParameter);
   VERIFY(pEvent != NULL);

   // Wait for the event to be signaled
   ::WaitForSingleObject(pEvent->m_hObject, INFINITE);

   // Terminate the thread
   ::AfxEndThread(0, FALSE); 
   return 0L;
}

void CEvent_Test()
{
   // Create the CEvent object that will be passed to the thread routine
   CEvent* pEvent = new CEvent(FALSE, FALSE);

   // Create a thread that will wait on the event
   CWinThread* pThread;
   pThread = ::AfxBeginThread(&MyThreadProc, pEvent, 0, 0, CREATE_SUSPENDED, NULL);
   pThread->m_bAutoDelete = FALSE; 
   pThread->ResumeThread();

   // Signal the thread to do the next work item
   pEvent->SetEvent();

   // Wait for the thread to consume the event and return
   ::WaitForSingleObject(pThread->m_hThread, INFINITE); 
   delete pThread;
   delete pEvent;
}
// This example builds upon the previous one. 
// A second thread is created to calculate prime numbers. 
// The main thread will signal the second thread to calulate the next  
// prime number in the series.  The second thread signals the first  
// after each number is calculated. Finally, after several iterations  
// the worker thread is signaled to terminate. 

class CPrimeTest
{
public:
   CPrimeTest()
      : m_pCalcNext(new CEvent(FALSE, FALSE))
      , m_pCalcFinished(new CEvent(FALSE, FALSE))
      , m_pTerminateThread(new CEvent(FALSE, FALSE))
      , m_iCurrentPrime(0)
   {   
      // Create a thread that will calculate the prime numbers
      CWinThread* pThread;
      pThread = ::AfxBeginThread(&PrimeCalcProc, this, 0, 0, CREATE_SUSPENDED, NULL);
      pThread->m_bAutoDelete = FALSE; 
      pThread->ResumeThread();

      // Calcuate the first 10 prime numbers in the series on the thread 
      for(UINT i = 0; i < 10; i++)
      {
         // Signal the thread to do the next work item
         m_pCalcNext->SetEvent();
         // Wait for the thread to complete the current task
         ::WaitForSingleObject(m_pCalcFinished->m_hObject, INFINITE);
         // Print the result
         TRACE(_T("The value of m_iCurrentPrime is: %d\n"), m_iCurrentPrime);
      }

      // Notify the worker thread to exit and wait for it to complete
      m_pTerminateThread->SetEvent();
      ::WaitForSingleObject(pThread->m_hThread, INFINITE); 
      delete pThread;
   }
   ~CPrimeTest()
   {
      delete m_pCalcNext;
      delete m_pCalcFinished;
      delete m_pTerminateThread;
   }

private:
   // Determines whether the given number is a prime number 
   static BOOL IsPrime(INT ThisPrime)
   {
      if(ThisPrime < 2) 
         return FALSE;

      for(INT n = 2; n < ThisPrime; n++)
      {
         if(ThisPrime % n == 0)
            return FALSE;
      }
      return TRUE;
   }

   // Calculates the next prime number in the series 
   static INT NextPrime(INT ThisPrime)
   {
      while(TRUE)
      {
         if(IsPrime(++ThisPrime))
         {
            return ThisPrime;
         }
      }
   }

   // Worker thread responsible for calculating the next prime 
   // number in the series 
   static UINT __cdecl PrimeCalcProc(LPVOID lpParameter)
   {
      CPrimeTest* pThis = static_cast<CPrimeTest*>(lpParameter);
      VERIFY(pThis != NULL);

      VERIFY(pThis->m_pCalcNext != NULL);
      VERIFY(pThis->m_pCalcFinished != NULL);
      VERIFY(pThis->m_pTerminateThread != NULL);

      // Create a CMultiLock object to wait on the various events 
      // WAIT_OBJECT_0 refers to the first event in the array, WAIT_OBJECT_0+1 refers to the second
      CSyncObject* pWaitObjects[] = { pThis->m_pCalcNext, pThis->m_pTerminateThread };
      CMultiLock MultiLock(pWaitObjects, 2L);
      while(MultiLock.Lock(INFINITE, FALSE) == WAIT_OBJECT_0) 
      {         
         // Calculate next prime
         pThis->m_iCurrentPrime = NextPrime(pThis->m_iCurrentPrime);
         // Notify main thread calculation is complete
         pThis->m_pCalcFinished->SetEvent();
       } 

      // Terminate the thread
       ::AfxEndThread(0, FALSE); 
      return 0L;
   }

   CEvent* m_pCalcNext;      // notifies worker thread to calculate next prime
   CEvent* m_pCalcFinished;   // notifies main thread current calculation is complete
   CEvent* m_pTerminateThread;   // notifies worker thread to terminate

   INT m_iCurrentPrime;   // current calculated prime number
};

Hierarquia de herança

CObject

CSyncObject

CEvent

Requisitos

Cabeçalho: afxmt.h

Consulte também

Referência

Classe CSyncObject

Gráfico da hierarquia