Delen via


Gebruik van One-Time-initialisatie

In de volgende voorbeelden ziet u het gebruik van de eenmalige initialisatiefuncties.

Synchroon voorbeeld

In dit voorbeeld is de g_InitOnce globale variabele de eenmalige initialisatiestructuur. Het wordt statisch geïnitialiseerd met behulp van INIT_ONCE_STATIC_INIT.

De functie OpenEventHandleSync retourneert een handle naar een gebeurtenis die slechts één keer wordt gecreëerd. De functie InitOnceExecuteOnce wordt aangeroepen om de initialisatiecode uit te voeren die is opgenomen in de InitHandleFunction callback-functie. Als de callback-functie slaagt, retourneert OpenEventHandleSync de event-handle die is geretourneerd in lpContext; anders retourneert het INVALID_HANDLE_VALUE.

De InitHandleFunction functie is de eenmalige initialisatieaanroepfunctie. InitHandleFunction roept de functie CreateEvent- aan om de gebeurtenis te maken en retourneert de gebeurtenisgreep in de parameter lpContext.

#define _WIN32_WINNT 0x0600
#include <windows.h>

// Global variable for one-time initialization structure
INIT_ONCE g_InitOnce = INIT_ONCE_STATIC_INIT; // Static initialization

// Initialization callback function 
BOOL CALLBACK InitHandleFunction (
    PINIT_ONCE InitOnce,        
    PVOID Parameter,            
    PVOID *lpContext);           

// Returns a handle to an event object that is created only once
HANDLE OpenEventHandleSync()
{
  PVOID lpContext;
  BOOL  bStatus;
  
  // Execute the initialization callback function 
  bStatus = InitOnceExecuteOnce(&g_InitOnce,          // One-time initialization structure
                                InitHandleFunction,   // Pointer to initialization callback function
                                NULL,                 // Optional parameter to callback function (not used)
                                &lpContext);          // Receives pointer to event object stored in g_InitOnce

  // InitOnceExecuteOnce function succeeded. Return event object.
  if (bStatus)
  {
    return (HANDLE)lpContext;
  }
  else
  {
    return (INVALID_HANDLE_VALUE);
  }
}

// Initialization callback function that creates the event object 
BOOL CALLBACK InitHandleFunction (
    PINIT_ONCE InitOnce,        // Pointer to one-time initialization structure        
    PVOID Parameter,            // Optional parameter passed by InitOnceExecuteOnce            
    PVOID *lpContext)           // Receives pointer to event object           
{
  HANDLE hEvent;

  // Create event object
  hEvent = CreateEvent(NULL,    // Default security descriptor
                       TRUE,    // Manual-reset event object
                       TRUE,    // Initial state of object is signaled 
                       NULL);   // Object is unnamed

  // Event object creation failed.
  if (NULL == hEvent)
  {
    return FALSE;
  }
  // Event object creation succeeded.
  else
  {
    *lpContext = hEvent;
    return TRUE;
  }
}

Asynchroon voorbeeld

In dit voorbeeld is de g_InitOnce globale variabele de eenmalige initialisatiestructuur. Het wordt statisch geïnitialiseerd met behulp van INIT_ONCE_STATIC_INIT.

De OpenEventHandleAsync functie geeft een verwijzing naar een event dat slechts één keer wordt aangemaakt. OpenEventHandleAsync roept de functie InitOnceBeginInitialize aan om de initialisatiestatus in te voeren.

Als de aanroep slaagt, controleert de code de waarde van de parameter fPending om te bepalen of de gebeurtenis moet worden gemaakt of gewoon een ingang retourneert naar de gebeurtenis die door een andere thread is gemaakt. Als fPendingFALSEis, is de initialisatie reeds voltooid, zodat OpenEventHandleAsync de gebeurtenis-handle retourneert die vanuit de parameter lpContext is verkregen. Anders wordt de functie CreateEvent aangeroepen om de gebeurtenis te maken en de functie InitOnceComplete om de initialisatie te voltooien.

Als de aanroep naar InitOnceComplete slaagt, retourneert OpenEventHandleAsync de nieuwe event-handle. Anders wordt de gebeurtenisgreep gesloten en wordt InitOnceBeginInitialize aangeroepen met INIT_ONCE_CHECK_ONLY om te bepalen of de initialisatie is mislukt of is voltooid door een andere thread.

Als de initialisatie is voltooid door een andere thread, retourneert OpenEventHandleAsync de gebeurtenis-handle die is geretourneerd in lpContext. Anders retourneert het INVALID_HANDLE_VALUE.

#define _WIN32_WINNT 0x0600
#include <windows.h>

// Global variable for one-time initialization structure
INIT_ONCE g_InitOnce = INIT_ONCE_STATIC_INIT; // Static initialization

// Returns a handle to an event object that is created only once
HANDLE OpenEventHandleAsync()
{
  PVOID  lpContext;
  BOOL   fStatus;
  BOOL   fPending;
  HANDLE hEvent;
  
  // Begin one-time initialization
  fStatus = InitOnceBeginInitialize(&g_InitOnce,       // Pointer to one-time initialization structure
                                    INIT_ONCE_ASYNC,   // Asynchronous one-time initialization
                                    &fPending,         // Receives initialization status
                                    &lpContext);       // Receives pointer to data in g_InitOnce  

  // InitOnceBeginInitialize function failed.
  if (!fStatus)
  {
    return (INVALID_HANDLE_VALUE);
  }

  // Initialization has already completed and lpContext contains event object.
  if (!fPending)
  {
    return (HANDLE)lpContext;
  }

  // Create event object for one-time initialization.
  hEvent = CreateEvent(NULL,    // Default security descriptor
                       TRUE,    // Manual-reset event object
                       TRUE,    // Initial state of object is signaled 
                       NULL);   // Object is unnamed

  // Event object creation failed.
  if (NULL == hEvent)
  {
    return (INVALID_HANDLE_VALUE);
  }

  // Complete one-time initialization.
  fStatus = InitOnceComplete(&g_InitOnce,             // Pointer to one-time initialization structure
                             INIT_ONCE_ASYNC,         // Asynchronous initialization
                             (PVOID)hEvent);          // Pointer to event object to be stored in g_InitOnce

  // InitOnceComplete function succeeded. Return event object.
  if (fStatus)
  {
    return hEvent;
  }
  
  // Initialization has already completed. Free the local event.
  CloseHandle(hEvent);


  // Retrieve the final context data.
  fStatus = InitOnceBeginInitialize(&g_InitOnce,            // Pointer to one-time initialization structure
                                    INIT_ONCE_CHECK_ONLY,   // Check whether initialization is complete
                                    &fPending,              // Receives initialization status
                                    &lpContext);            // Receives pointer to event object in g_InitOnce
  
  // Initialization is complete. Return handle.
  if (fStatus && !fPending)
  {
    return (HANDLE)lpContext;
  }
  else
  {
    return INVALID_HANDLE_VALUE;
  }
}

One-Time initialisatie