Dela via


Asynkron körning (meddelandemetod)

ODBC tillåter asynkron körning av anslutnings- och instruktionsåtgärder. En programtråd kan anropa en ODBC-funktion i asynkront läge och funktionen kan returneras innan åtgärden är klar, vilket gör att programtråden kan utföra andra uppgifter. I Windows 7-SDK:n, för asynkrona instruktions- eller anslutningsåtgärder, bestämde ett program att den asynkrona operationen slutfördes med hjälp av polling-metoden. Mer information finns i Asynkron körning (pollning). Från och med Windows 8 SDK kan du fastställa att en asynkron åtgärd har slutförts med hjälp av meddelandemetoden.

I avsökningsmetoden måste program anropa den asynkrona funktionen varje gång den vill ha status för åtgärden. Meddeleringsmetoden liknar återanrop och väntning i ADO.NET. ODBC använder dock Win32-händelser som meddelandeobjekt.

ODBC-markörbiblioteket och ODBC-asynkrona meddelanden kan inte användas samtidigt. Om du anger båda attributen returneras ett fel med SQLSTATE S1119 (Markörbibliotek och Asynkront meddelande kan inte aktiveras samtidigt).

För information till drivrutinsutvecklare, se Meddelande om Asynkron funktionsavslut.

Anmärkning

Meddelandemetoden stöds inte med markörbiblioteket. Ett program får ett felmeddelande om det försöker aktivera markörbiblioteket via SQLSetConnectAttr när meddelandemetoden är aktiverad.

Översikt

När en ODBC-funktion anropas i asynkront läge, returneras kontrollen till det anropande programmet omedelbart med returkoden SQL_STILL_EXECUTING. Programmet måste avsöka funktionen upprepade gånger tills den returnerar något annat än SQL_STILL_EXECUTING. Avsökningsloopen ökar processoranvändningen, vilket orsakar dåliga prestanda i många asynkrona scenarier.

När meddelandemodellen används inaktiveras avsökningsmodellen. Program bör inte anropa den ursprungliga funktionen igen. Anropa FUNKTIONEN SQLCompleteAsync för att slutföra den asynkrona åtgärden. Om ett program anropar den ursprungliga funktionen igen innan den asynkrona åtgärden är klar returnerar anropet SQL_ERROR med SQLSTATE IM017 (avsökning är inaktiverat i asynkront meddelandeläge).

När du använder meddelandemodellen kan programmet anropa SQLCancel eller SQLCancelHandle för att avbryta en instruktion eller anslutningsåtgärd. Om avbokningsbegäran lyckas returnerar ODBC SQL_SUCCESS. Det här meddelandet anger inte att funktionen faktiskt avbröts. det anger att avbokningsbegäran bearbetades. Om funktionen faktiskt avbryts beror på drivrutinen och datakällan. När en åtgärd avbryts kommer driver manager fortfarande att signalera händelsen. Driver Manager returnerar SQL_ERROR i returkodbufferten och tillståndet är SQLSTATE HY008 (åtgärden avbröts) för att indikera att annulleringen lyckades. Om funktionen har slutfört sin normala bearbetning returnerar Driver Manager SQL_SUCCESS eller SQL_SUCCESS_WITH_INFO.

Beteende på nednivå

ODBC Driver Manager-versionen som stöder denna fullständighetsavisering är ODBC 3.81.

Odbc-version för program Drivrutinshanterarens version Version av drivrutin Beteende
Nytt program för valfri ODBC-version ODBC 3.81 ODBC 3.80-drivrutin Programmet kan använda den här funktionen om drivrutinen stöder den här funktionen, annars kommer Drivrutinshanteraren att fela.
Nytt program för valfri ODBC-version ODBC 3.81 Pre-ODBC 3.80 drivrutin Drivrutinshanteraren får ett felmeddelande om drivrutinen inte stöder den här funktionen.
Nytt program för valfri ODBC-version Pre-ODBC 3.81 Vilken som helst När programmet använder den här funktionen kommer en gammal Driver Manager att betrakta de nya attributen som drivrutinspecifika attribut, och drivrutinen borde ge ett felmeddelande. En ny Driver Manager kommer inte att skicka dessa attribut till drivrutinen.

Ett program bör kontrollera Driver Manager-versionen innan du använder den här funktionen. Annars, om en dåligt skriven drivrutin inte resulterar i ett fel och Driver Manager-versionen är före ODBC 3.81, är beteendet odefinierat.

Användningsfall

Det här avsnittet visar användningsfall för asynkron körning och pollingmekanismen.

Integrera data från flera ODBC-källor

Ett dataintegreringsprogram hämtar asynkront data från flera datakällor. Vissa data kommer från fjärranslutna datakällor och vissa data kommer från lokala filer. Programmet kan inte fortsätta förrän de asynkrona åtgärderna har slutförts.

I stället för att upprepade gånger avsöka en åtgärd för att avgöra om den är klar kan programmet skapa ett händelseobjekt och associera det med en ODBC-anslutningsreferens eller en ODBC-instruktionsreferens. Programmet anropar sedan API:er för operativsystemsynkronisering för att vänta på ett händelseobjekt eller många händelseobjekt (både ODBC-händelser och andra Windows-händelser). ODBC signalerar händelseobjektet när motsvarande ODBC-asynkrona åtgärd har slutförts.

I Windows används Win32-händelseobjekt och det ger användaren en enhetlig programmeringsmodell. Drivrutinshanterare på andra plattformar kan använda händelseobjektimplementeringen som är specifik för dessa plattformar.

Följande kodexempel visar användningen av ett asynkront meddelande om anslutning och -instruktion:

// This function opens NUMBER_OPERATIONS connections and executes one query on statement of each connection.  
// Asynchronous Notification is used  
  
#define NUMBER_OPERATIONS 5  
int AsyncNotificationSample(void)  
{  
    RETCODE     rc;  
  
    SQLHENV     hEnv              = NULL;  
    SQLHDBC     arhDbc[NUMBER_OPERATIONS]         = {NULL};  
    SQLHSTMT    arhStmt[NUMBER_OPERATIONS]        = {NULL};  
  
    HANDLE      arhDBCEvent[NUMBER_OPERATIONS]    = {NULL};  
    RETCODE     arrcDBC[NUMBER_OPERATIONS]        = {0};  
    HANDLE      arhSTMTEvent[NUMBER_OPERATIONS]   = {NULL};  
    RETCODE     arrcSTMT[NUMBER_OPERATIONS]       = {0};  
  
    rc = SQLAllocHandle(SQL_HANDLE_ENV, NULL, &hEnv);  
    if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
  
    rc = SQLSetEnvAttr(hEnv,  
        SQL_ATTR_ODBC_VERSION,  
        (SQLPOINTER) SQL_OV_ODBC3_80,  
        SQL_IS_INTEGER);  
    if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
  
    // Connection operations begin here  
  
    // Alloc NUMBER_OPERATIONS connection handles  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        rc = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &arhDbc[i]);  
        if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
    }  
  
    // Enable DBC Async on all connection handles  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        rc= SQLSetConnectAttr(arhDbc[i], SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, (SQLPOINTER)SQL_ASYNC_DBC_ENABLE_ON, SQL_IS_INTEGER);  
        if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
    }  
  
    // Application must create event objects  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        arhDBCEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL); // Auto-reset, initial state is not-signaled  
        if (!arhDBCEvent[i]) goto Cleanup;  
    }  
  
    // Enable notification on all connection handles  
    // Event  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        rc= SQLSetConnectAttr(arhDbc[i], SQL_ATTR_ASYNC_DBC_EVENT, arhDBCEvent[i], SQL_IS_POINTER);  
        if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
    }  
  
    // Initiate connect establishing  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        SQLDriverConnect(arhDbc[i], NULL, (SQLTCHAR*)TEXT("Driver={ODBC Driver 11 for SQL Server};SERVER=dp-srv-sql2k;DATABASE=pubs;UID=sa;PWD=XYZ;"), SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);  
    }  
  
    // Can do some other staff before calling WaitForMultipleObjects  
    WaitForMultipleObjects(NUMBER_OPERATIONS, arhDBCEvent, TRUE, INFINITE); // Wait All  
  
    // Complete connect API calls  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        SQLCompleteAsync(SQL_HANDLE_DBC, arhDbc[i], & arrcDBC[i]);  
    }  
  
    BOOL fFail = FALSE; // Whether some connection opening fails.  
  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if ( !SQL_SUCCEEDED(arrcDBC[i]) )   
            fFail = TRUE;  
    }  
  
    // If some SQLDriverConnect() fail, clean up.  
    if (fFail)  
    {  
        for (int i=0; i<NUMBER_OPERATIONS; i++)  
        {  
            if (SQL_SUCCEEDED(arrcDBC[i]) )   
            {  
                SQLDisconnect(arhDbc[i]); // This is also async  
            }  
            else  
            {  
                SetEvent(arhDBCEvent[i]); // Previous SQLDriverConnect() failed. No need to call SQLDisconnect().  
            }  
        }  
        WaitForMultipleObjects(NUMBER_OPERATIONS, arhDBCEvent, TRUE, INFINITE);   
        for (int i=0; i<NUMBER_OPERATIONS; i++)  
        {  
            if (SQL_SUCCEEDED(arrcDBC[i]) )   
            {     
                SQLCompleteAsync(SQL_HANDLE_DBC, arhDbc[i], &arrcDBC[i]);; // To Complete  
            }  
        }  
  
        goto Cleanup;  
    }  
  
    // Statement Operations begin here  
  
    // Alloc statement handle  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        rc = SQLAllocHandle(SQL_HANDLE_STMT, arhDbc[i], &arhStmt[i]);  
        if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
    }  
  
    // Enable STMT Async on all statement handles  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        rc = SQLSetStmtAttr(arhStmt[i], SQL_ATTR_ASYNC_ENABLE, (SQLPOINTER)SQL_ASYNC_ENABLE_ON, SQL_IS_INTEGER);  
        if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
    }  
  
    // Create event objects  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        arhSTMTEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL); // Auto-reset, initial state is not-signaled  
        if (!arhSTMTEvent[i]) goto Cleanup;  
    }  
  
    // Enable notification on all statement handles  
    // Event  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        rc= SQLSetStmtAttr(arhStmt[i], SQL_ATTR_ASYNC_STMT_EVENT, arhSTMTEvent[i], SQL_IS_POINTER);  
        if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
    }  
  
    // Initiate SQLExecDirect() calls  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        SQLExecDirect(arhStmt[i], (SQLTCHAR*)TEXT("select au_lname, au_fname from authors"), SQL_NTS);  
    }  
  
    // Can do some other staff before calling WaitForMultipleObjects  
    WaitForMultipleObjects(NUMBER_OPERATIONS, arhSTMTEvent, TRUE, INFINITE); // Wait All  
  
    // Now, call SQLCompleteAsync to complete the operation and get return code  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        SQLCompleteAsync(SQL_HANDLE_STMT, arhStmt[i], &arrcSTMT[i]);  
    }  
  
    // Check return values  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if ( !SQL_SUCCEEDED(arrcSTMT[i]) ) goto Cleanup;  
    }  
  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        //Do some binding jobs here, set SQL_ATTR_ROW_ARRAY_SIZE   
    }  
  
    // Now, initiate fetching  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        SQLFetch(arhStmt[i]);  
    }  
  
    // Can do some other staff before calling WaitForMultipleObjects  
    WaitForMultipleObjects(NUMBER_OPERATIONS, arhSTMTEvent, TRUE, INFINITE);   
  
    // Now, to complete the operations and get return code  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        SQLCompleteAsync(SQL_HANDLE_STMT, arhStmt[i], &arrcSTMT[i]);  
    }  
  
    // Check return code  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if ( !SQL_SUCCEEDED(arrcSTMT[i]) ) goto Cleanup;  
    }  
  
    // USE fetched data here!!  
  
Cleanup:  
  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if (arhStmt[NUMBER_OPERATIONS])  
        {  
            SQLFreeHandle(SQL_HANDLE_STMT, arhStmt[i]);  
            arhStmt[i] = NULL;  
        }  
    }  
  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if (arhSTMTEvent[i])  
        {  
            CloseHandle(arhSTMTEvent[i]);  
            arhSTMTEvent[i] = NULL;  
        }  
    }  
  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if (arhDbc[i])  
        {  
            SQLFreeHandle(SQL_HANDLE_DBC, arhDbc[i]);  
            arhDbc[i] = NULL;  
        }  
    }  
  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if (arhDBCEvent[i])  
        {  
            CloseHandle(arhDBCEvent[i]);  
            arhDBCEvent[i] = NULL;  
        }  
    }  
  
    if (hEnv)  
    {  
        SQLFreeHandle(SQL_HANDLE_ENV, hEnv);  
        hEnv = NULL;  
    }  
  
    return 0;  
}  
  

Avgöra om en drivrutin stöder asynkrona meddelanden

Ett ODBC-program kan avgöra om en ODBC-drivrutin stöder asynkrona meddelanden genom att anropa SQLGetInfo. ODBC Driver Manager anropar därför SQLGetInfo för drivrutinen med SQL_ASYNC_NOTIFICATION.

SQLUINTEGER InfoValue;  
SQLLEN      cbInfoLength;  
  
SQLRETURN retcode;  
retcode = SQLGetInfo (hDbc,   
                      SQL_ASYNC_NOTIFICATION,   
                      &InfoValue,  
                      sizeof(InfoValue),  
                      NULL);  
if (SQL_SUCCEEDED(retcode))  
{  
if (SQL_ASYNC_NOTIFICATION_CAPABLE == InfoValue)  
      {  
          // The driver supports asynchronous notification  
      }  
      else if (SQL_ASYNC_NOTIFICATION_NOT_CAPABLE == InfoValue)  
      {  
          // The driver does not support asynchronous notification  
      }  
}  

Associera ett Win32-händelsehandtag med ett ODBC-handtag

Program ansvarar för att skapa Win32-händelseobjekt med hjälp av motsvarande Win32-funktioner. Ett program kan associera en Win32-händelsereferens med en ODBC-anslutningsreferens eller en ODBC-instruktionsreferens.

Anslutningsattribut SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE och SQL_ATTR_ASYNC_DBC_EVENT avgöra om ODBC körs i asynkront läge och om ODBC aktiverar meddelandeläge för en anslutningsreferens. Instruktionsattribut SQL_ATTR_ASYNC_ENABLE och SQL_ATTR_ASYNC_STMT_EVENT avgöra om ODBC körs i asynkront läge och om ODBC aktiverar meddelandeläge för en instruktionsreferens.

SQL_ATTR_ASYNC_ENABLE eller SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE SQL_ATTR_ASYNC_STMT_EVENT eller SQL_ATTR_ASYNC_DBC_EVENT Mode
Enable icke-null Asynkront meddelande
Enable noll Asynkron avsökning
Disable any Synchronous

Ett program kan tillfälligt inaktivera asynkront åtgärdsläge. ODBC ignorerar värden för SQL_ATTR_ASYNC_DBC_EVENT om asynkron åtgärd på anslutningsnivå är inaktiverad. ODBC ignorerar värden för SQL_ATTR_ASYNC_STMT_EVENT om instruktionsnivån asynkron åtgärd är inaktiverad.

Synkront anrop av SQLSetStmtAttr och SQLSetConnectAttr

  • SQLSetConnectAttr stöder asynkrona åtgärder, men anropet av SQLSetConnectAttr för att ange SQL_ATTR_ASYNC_DBC_EVENT är alltid synkront.

  • SQLSetStmtAttr stöder inte asynkron körning.

Scenario med fel
När SQLSetConnectAttr anropas innan en anslutning upprättas kan driverhanteraren inte avgöra vilken drivrutin som ska användas. Därför returnerar Driver Manager framgång för SQLSetConnectAttr , men attributet kanske inte är redo att anges i drivrutinen. Drivrutinshanteraren anger dessa attribut när programmet anropar en anslutningsfunktion. Drivrutinshanteraren kan ha fel eftersom drivrutinen inte stöder asynkrona åtgärder.

Arv av anslutningsattribut
Uttryck för en anslutning ärver vanligtvis anslutningsattributen. Attributet SQL_ATTR_ASYNC_DBC_EVENT är dock inte ärverbart och påverkar bara anslutningsåtgärderna.

För att associera en händelsereferens med en ODBC-anslutningsreferens anropar ett ODBC-program ODBC API SQLSetConnectAttr och anger SQL_ATTR_ASYNC_DBC_EVENT som attribut och händelsereferens som attributvärde. Det nya ODBC-attributet SQL_ATTR_ASYNC_DBC_EVENT är av typen SQL_IS_POINTER.

HANDLE hEvent;  
hEvent = CreateEvent(   
            NULL,                // default security attributes  
            FALSE,               // auto-reset event  
            FALSE,               // initial state is non-signaled  
            NULL                 // no name  
            );  

Vanligtvis skapar program händelseobjekt för automatisk återställning. ODBC återställer inte händelseobjektet. Program måste se till att objektet inte är i signalerat tillstånd innan någon asynkron ODBC-funktion anropas.

SQLRETURN retcode;  
retcode = SQLSetConnectAttr ( hDBC,  
                              SQL_ATTR_ASYNC_DBC_EVENT, // Attribute name  
                              (SQLPOINTER) hEvent,      // Win32 Event handle  
                              SQL_IS_POINTER);          // Length Indicator  

SQL_ATTR_ASYNC_DBC_EVENT är ett attribut som endast används av Drivrutinshanteraren och kommer inte att anges i drivrutinen.

Standardvärdet för SQL_ATTR_ASYNC_DBC_EVENT är NULL. Om drivrutinen inte stöder asynkrona meddelanden returneras SQL_ERROR med SQLSTATE HY092 (ogiltig attribut-/alternatividentifierare) om du hämtar eller anger SQL_ATTR_ASYNC_DBC_EVENT.

Om det sista SQL_ATTR_ASYNC_DBC_EVENT värdet som angetts för en ODBC-anslutningsreferens inte är NULL och programmet har aktiverat asynkront läge genom att ange attributet SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE med SQL_ASYNC_DBC_ENABLE_ON, får anrop av en ODBC-anslutningsfunktion som stöder asynkront läge ett slutförandemeddelande. Om det sista SQL_ATTR_ASYNC_DBC_EVENT värdet som angetts för en ODBC-anslutningsreferens är NULL, skickar ODBC inte något meddelande till programmet, oavsett om asynkront läge är aktiverat.

Ett program kan ange SQL_ATTR_ASYNC_DBC_EVENT före eller efter inställningen av attributet SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE.

Program kan ange attributet SQL_ATTR_ASYNC_DBC_EVENT på en ODBC-anslutningsreferens innan du anropar en anslutningsfunktion (SQLConnect, SQLBrowseConnect eller SQLDriverConnect). Eftersom ODBC Driver Manager inte vet vilken ODBC-drivrutin programmet ska använda returneras SQL_SUCCESS. När programmet anropar en anslutningsfunktion kontrollerar ODBC Driver Manager om drivrutinen stöder asynkrona meddelanden. Om drivrutinen inte stöder asynkrona meddelanden returnerar ODBC Driver Manager SQL_ERROR med SQLSTATE S1_118 (drivrutinen stöder inte asynkrona meddelanden). Om drivrutinen stöder asynkrona meddelanden anropar ODBC Driver Manager drivrutinen och anger motsvarande attribut SQL_ATTR_ASYNC_DBC_NOTIFICATION_CALLBACK och SQL_ATTR_ASYNC_DBC_NOTIFICATION_CONTEXT.

På samma sätt anropar ett program SQLSetStmtAttr på en ODBC-instruktionsreferens och anger attributet SQL_ATTR_ASYNC_STMT_EVENT för att aktivera eller inaktivera asynkrona meddelanden på instruktionsnivå. Eftersom en instruktionsfunktion alltid anropas när anslutningen har upprättats returnerar SQLSetStmtAttr SQL_ERROR med SQLSTATE S1_118 (drivrutinen stöder inte asynkront meddelande) omedelbart om motsvarande drivrutin inte stöder asynkrona åtgärder eller om drivrutinen stöder asynkron åtgärd men inte stöder asynkrona meddelanden.

SQLRETURN retcode;  
retcode = SQLSetStmtAttr ( hSTMT,  
                           SQL_ATTR_ASYNC_STMT_EVENT, // Attribute name   
                           (SQLPOINTER) hEvent,       // Win32 Event handle  
                           SQL_IS_POINTER);           // length Indicator  

SQL_ATTR_ASYNC_STMT_EVENT, som kan anges till NULL, är ett attribut endast för Driver Manager som inte anges i drivrutinen.

Standardvärdet för SQL_ATTR_ASYNC_STMT_EVENT är NULL. Om drivrutinen inte stöder asynkrona meddelanden returneras SQL_ERROR med SQLSTATE HY092 (ogiltigt attribut/alternatividentifierare) om du hämtar eller anger attributet SQL_ATTR_ASYNC_ STMT_EVENT.

Ett program bör inte associera samma händelsehandtag med mer än ett ODBC-handtag. Annars går en notifiering förlorad om två asynkrona ODBC-funktionsanrop slutförs på två handtag som delar samma händelsehandtag. För att undvika att ett instruktionshandtag ärver samma händelsehandtag från anslutningshandtaget returnerar ODBC SQL_ERROR med SQLSTATE IM016 (Det går inte att ange instruktionsattribut i anslutningshandtaget) om en applikation sätter SQL_ATTR_ASYNC_STMT_EVENT på ett anslutningshandtag.

Anropa asynkrona ODBC-funktioner

När du har aktiverat asynkrona meddelanden och startat en asynkron åtgärd kan programmet anropa valfri ODBC-funktion. Om funktionen tillhör den uppsättning funktioner som stöder asynkron åtgärd får programmet ett slutförandemeddelande när åtgärden slutförs, oavsett om funktionen misslyckades eller lyckades. Det enda undantaget är att programmet anropar en ODBC-funktion med en ogiltig anslutnings- eller instruktionsreferens. I det här fallet kommer ODBC inte att få händelsehandtaget och ställa in det till det signalerade tillståndet.

Programmet måste se till att det associerade händelseobjektet är i ett icke-signalerat tillstånd innan en asynkron åtgärd startas på motsvarande ODBC-handtag. ODBC återställer inte händelseobjektet.

Få meddelande från ODBC

En programtråd kan anropa WaitForSingleObject för att vänta på en händelsereferens eller anropa WaitForMultipleObjects för att vänta på en matris med händelsehandtag och pausas tills ett eller alla händelseobjekt signaleras eller tidsgränsintervallet förflutit.

DWORD dwStatus = WaitForSingleObject(  
                        hEvent,  // The event associated with the ODBC handle  
                        5000     // timeout is 5000 millisecond   
);  
  
If (dwStatus == WAIT_TIMEOUT)  
{  
    // time-out interval elapsed before all the events are signaled.   
}  
Else  
{  
    // Call the corresponding Asynchronous ODBC API to complete all processing and retrieve the return code.  
}