Transaktionshantering (Data Exchange)
När en konversation har upprättats med en server kan en klient skicka transaktioner för att hämta data och tjänster från servern.
I följande avsnitt beskrivs vilka typer av transaktioner som klienter kan använda för att interagera med en server.
- Begär transaktion
- Poke Transaction
- ge råd om
- köra
- synkrona och asynkrona transaktioner
- transaktionskontroll
- transaktionsklasser
- transaktionstyper
Begär transaktion
Ett klientprogram kan använda XTYP_REQUEST transaktion för att begära ett dataobjekt från ett serverprogram. Klienten anropar funktionen DdeClientTransaction, anger XTYP_REQUEST som transaktionstyp och anger det dataobjekt som programmet behöver.
DDEML (Dynamic Data Exchange Management Library) skickar XTYP_REQUEST transaktionen till servern och anger ämnesnamnet, objektnamnet och dataformatet som begärs av klienten. Om servern stöder det begärda ämnet, objektet och formatet ska servern returnera en datareferens som identifierar objektets aktuella värde. DDEML skickar handtaget till klienten som returvärde från DdeClientTransaction. Servern bör returnera NULL- om den inte stöder det begärda ämnet, objektet eller formatet.
DdeClientTransaction använder parametern lpdwResult för att returnera en transaktionsstatusflagga till klienten. Om servern inte bearbetar XTYP_REQUEST transaktion returnerar DdeClientTransactionNULL-och lpdwResult pekar på flaggan DDE_FNOTPROCESSED eller DDE_FBUSY. Om flaggan DDE_FNOTPROCESSED returneras kan klienten inte avgöra varför servern inte bearbetade transaktionen.
Om en server inte stöder XTYP_REQUEST transaktion bör den ange CBF_FAIL_REQUESTS filterflaggan i funktionen DdeInitialize. Den här flaggan förhindrar att DDEML skickar transaktionen till servern.
Peta transaktion
En klient kan skicka oönskad data till en server med hjälp av DdeClientTransaction för att skicka en XTYP_POKE transaktion till en servers återanropsfunktion.
Klientprogrammet skapar först en buffert som innehåller de data som ska skickas till servern och skickar sedan en pekare till bufferten som en parameter för att DdeClientTransaction. Alternativt kan klienten använda funktionen DdeCreateDataHandle för att hämta ett datahandtag som identifierar data och sedan skicka handtaget till DdeClientTransaction. I båda fallen anger klienten även ämnesnamn, objektnamn och dataformat när den anropar DdeClientTransaction.
DDEML skickar XTYP_POKE transaktionen till servern och anger ämnesnamn, objektnamn och dataformat som klienten begärde. För att acceptera dataobjektet och formatet bör servern returnera DDE_FACK. Om du vill avvisa data bör servern returnera DDE_FNOTPROCESSED. Om servern är för upptagen för att acceptera data bör servern returnera DDE_FBUSY.
När DdeClientTransaction- returnerar kan klienten använda parametern lpdwResult för att komma åt flaggan för transaktionsstatus. Om flaggan är DDE_FBUSY bör klienten skicka transaktionen igen senare.
Om en server inte stöder XTYP_POKE transaktion bör den ange CBF_FAIL_POKES filterflaggan i DdeInitialize. Den här flaggan förhindrar att DDEML skickar den här transaktionen till servern.
Råda transaktion
Ett klientprogram kan använda DDEML för att upprätta en eller flera länkar till objekt i ett serverprogram. När en sådan länk har upprättats skickar servern regelbundna uppdateringar om det länkade objektet till klienten (vanligtvis när värdet för det objekt som är associerat med serverprogrammet ändras). Länkning upprättar en rådgivningsloop mellan de två program som finns kvar tills klienten avslutar den.
Det finns två typer av rådsloopar: "heta" och "varma". I en loop med frekventa råd skickar servern omedelbart ett datahandtag som identifierar det ändrade värdet. I en varm rekommenderad loop meddelar servern klienten att värdet för objektet har ändrats men inte skickar datahandtaget förrän klienten begär det.
En klient kan begära en snabbupplysningsloop med en server genom att ange XTYP_ADVSTART transaktionstyp i ett anrop till DdeClientTransaction. Om du vill begära en varm rekommenderad loop måste klienten kombinera flaggan XTYPF_NODATA med XTYP_ADVSTART transaktionstyp. I båda dessa fall skickar DDEML XTYP_ADVSTART transaktionen till serverns återanropsfunktion För dynamiskt datautbyte (DDE). Serverns DDE-återanropsfunktion bör undersöka parametrarna som medföljer den XTYP_ADVSTART transaktionen (inklusive det begärda formatet, ämnesnamnet och objektnamnet) och sedan returnera TRUE- för att ge rådsloopen eller FALSE- att neka den.
När en rådgivningsloop har upprättats bör serverprogrammet anropa funktionen DdePostAdvise när värdet för objektet som är associerat med det begärda objektnamnet ändras. Det här anropet resulterar i att en XTYP_ADVREQ transaktion skickas till serverns egen DDE-återanropsfunktion. Serverns DDE-återanropsfunktion ska returnera ett datahandtag som identifierar det nya värdet för dataobjektet. DDEML meddelar sedan klienten att det angivna objektet har ändrats genom att skicka XTYP_ADVDATA transaktionen till klientens DDE-återanropsfunktion.
Om klienten begärde en frekvent rådgivningsloop skickar DDEML datahandtaget till det ändrade objektet till klienten under den XTYP_ADVDATA transaktionen. Annars kan klienten skicka en XTYP_REQUEST transaktion för att hämta datahandtaget.
Det är möjligt för en server att skicka uppdateringar snabbare än en klient kan bearbeta nya data. Uppdateringshastigheten kan vara ett problem för en klient som måste utföra långa bearbetningsåtgärder på data. I det här fallet bör klienten ange flaggan XTYPF_ACKREQ när den begär en rådgivningsloop. Den här flaggan gör att servern väntar på att klienten ska bekräfta att den har tagit emot och bearbetat ett dataobjekt innan servern skickar nästa dataobjekt. Rekommendera loopar som upprättas med flaggan XTYPF_ACKREQ är mer robusta med snabba servrar men kan ibland missa uppdateringar. Rådsloopar som upprättas utan flaggan XTYPF_ACKREQ kommer garanterat inte att missa uppdateringar så länge klienten håller sig uppdaterad med servern.
En klient kan avsluta en rådgivningsloop genom att ange XTYP_ADVSTOP transaktionstyp i ett anrop till DdeClientTransaction.
Om en server inte stöder rådsloopar bör den ange CBF_FAIL_ADVISES-filterflaggan i funktionen DdeInitialize. Den här flaggan förhindrar att DDEML skickar XTYP_ADVSTART- och XTYP_ADVSTOP transaktioner till servern.
Kör transaktion
En klient kan använda XTYP_EXECUTE transaktion för att få en server att köra ett kommando eller en serie kommandon.
För att köra ett serverkommando skapar klienten först en buffert som innehåller en kommandosträng som servern ska köra och skickar sedan antingen en pekare till bufferten eller ett datahandtag som identifierar bufferten när den anropar DdeClientTransaction. Andra obligatoriska parametrar är konversationshandtaget, stränghandtaget för objektnamn, formatspecifikationen och XTYP_EXECUTE transaktionstyp. Ett program som skapar en datareferens för att skicka körningsdata måste ange NULL- för parametern hszItem för DdeCreateDataHandle-funktionen och noll för parametern uFmt.
DDEML skickar XTYP_EXECUTE transaktionen till serverns DDE-återanropsfunktion och anger formatnamnet, konversationshandtaget, ämnesnamnet och datahandtaget som identifierar kommandosträngen. Om servern stöder kommandot bör den använda funktionen DdeAccessData för att hämta en pekare till kommandosträngen, köra kommandot och sedan returnera DDE_FACK. Om servern inte stöder kommandot eller inte kan slutföra transaktionen bör den returnera DDE_FNOTPROCESSED. Servern bör returnera DDE_FBUSY om den är för upptagen för att slutföra transaktionen.
I allmänhet bör en servers återanropsfunktion bearbeta den XTYP_EXECUTE transaktionen innan den returneras med följande undantag:
- När kommandot skickades med den XTYP_EXECUTE transaktionen begär att servern ska avslutas bör servern inte avslutas förrän dess återanropsfunktion returnerar från bearbetningen XTYP_EXECUTE.
- Om servern måste utföra en åtgärd, till exempel bearbetning av en dialogruta eller en DDE-transaktion som kan orsaka DDEML-rekursionsproblem, bör servern returnera CBR_BLOCK returnera kod för att blockera körningstransaktionen, utföra åtgärden och sedan återuppta bearbetningen av körningstransaktionen.
När DdeClientTransaction- returnerar kan klienten använda parametern lpdwResult för att få åtkomst till transaktionsstatusflaggan. Om flaggan är DDE_FBUSY bör klienten skicka transaktionen igen senare.
Om en server inte stöder XTYP_EXECUTE transaktion bör den ange CBF_FAIL_EXECUTES filterflaggan i funktionen DdeInitialize. Detta förhindrar att DDEML skickar transaktionen till servern.
Synkrona och asynkrona transaktioner
En klient kan skicka synkrona eller asynkrona transaktioner. I en synkron transaktion anger klienten ett timeout-värde som anger den maximala tidsperiod som servern ska vänta på att transaktionen ska bearbetas. DdeClientTransaction inte returneras förrän servern bearbetar transaktionen, transaktionen misslyckas eller tidsgränsvärdet upphör att gälla. Klienten anger tidsgränsvärdet när den anropar DdeClientTransaction.
Under en synkron transaktion anger klienten en modal-loop i väntan på att transaktionen ska bearbetas. Klienten kan fortfarande bearbeta användarindata men kan inte skicka en annan synkron transaktion förrän DdeClientTransaction returnerar.
En klient skickar en asynkron transaktion genom att ange flaggan TIMEOUT_ASYNC i DdeClientTransaction. Funktionen returnerar när transaktionen har påbörjats och skickar en transaktionsidentifierare till klienten. När servern har slutfört bearbetningen av den asynkrona transaktionen skickar DDEML en XTYP_XACT_COMPLETE transaktion till klienten. En av parametrarna som DDEML skickar till klienten under den XTYP_XACT_COMPLETE transaktionen är transaktionsidentifieraren. Genom att jämföra transaktionsidentifieraren med identifieraren som returnerades av DdeClientTransactionidentifierar klienten vilken asynkron transaktion servern har slutfört bearbetningen.
En klient kan använda funktionen DdeSetUserHandle som hjälp vid bearbetning av en asynkron transaktion. Den här funktionen gör det möjligt för en klient att associera ett programdefinierat värde med ett konversationshandtag och en transaktionsidentifierare. Klienten kan använda funktionen DdeQueryConvInfo under den XTYP_XACT_COMPLETE transaktionen för att hämta det programdefinierade värdet. På grund av den här funktionen behöver ett program inte underhålla en lista över aktiva transaktionsidentifierare.
När en klient slutför en begäran om data med en synkron transaktion kan DDEML inte se när klienten har slutfört användningen av mottagna data. Klientprogrammet måste skicka datahandtaget som tagits emot till funktionen DdeFreeDataHandle och meddela DDEML att handtaget inte längre kommer att användas. Datahandtag som returneras av synkrona transaktioner ägs effektivt av klienten.
Om en server inte bearbetar en asynkron transaktion i tid kan klienten avbryta transaktionen genom att anropa funktionen DdeAbandonTransaction. DDEML släpper alla resurser som är associerade med transaktionen och tar bort resultatet av transaktionen när servern är klar med bearbetningen. En timeout under en synkron transaktion avbryter effektivt transaktionen.
Den asynkrona transaktionsmetoden tillhandahålls för program som måste skicka en stor mängd DDE-transaktioner samtidigt som en betydande mängd bearbetning utförs, till exempel att utföra beräkningar. Den asynkrona metoden är också användbar i program som tillfälligt måste sluta bearbeta DDE-transaktioner så att de kan utföra andra uppgifter utan avbrott. I de flesta andra situationer bör ett program använda den synkrona metoden.
Synkrona transaktioner är enklare att underhålla och är snabbare än asynkrona transaktioner. Det går dock bara att utföra en synkron transaktion i taget, medan många asynkrona transaktioner kan utföras samtidigt. Med synkrona transaktioner kan en långsam server göra att en klient förblir inaktiv medan den väntar på ett svar. Synkrona transaktioner gör också att klienten anger en modal loop som kan kringgå meddelandefiltrering i programmets egen meddelandeloop.
Om klienten har installerat en krokprocedur för att filtrera meddelanden (det vill säga den WH_MSGFILTER hook-typen i ett anrop till funktionen SetWindowsHookEx) kommer en synkron transaktion inte att göra så att systemet kringgår hookproceduren. När en indatahändelse inträffar medan klienten väntar på att en synkron transaktion ska avslutas, får hook-proceduren en MSGF_DDEMGR hook-kod. Den största risken med att använda en synkron transaktionsmodal-loop är att en modal loop som skapas av en dialogruta kan störa dess åtgärd. Asynkrona transaktioner bör alltid användas när DDEML används av en DLL.
Transaktionskontroll
Ett program kan pausa transaktioner till dess DDE-återanropsfunktion, antingen de transaktioner som är associerade med en specifik konversationsreferens eller alla transaktioner oavsett konversationshandtaget. Den här funktionen är användbar när ett program tar emot en transaktion som kräver lång bearbetning. I sådana fall kan programmet returnera CBR_BLOCK returnera kod för att pausa framtida transaktioner som är associerade med transaktionens konversationshandtag, så att programmet kan bearbeta andra konversationer.
När bearbetningen har slutförts anropar programmet funktionen DdeEnableCallback för att återuppta transaktioner som är associerade med den pausade konversationen. Att anropa DdeEnableCallback gör att DDEML skickar om transaktionen som resulterade i att programmet avbröt konversationen. Därför bör programmet lagra resultatet av transaktionen på ett sådant sätt att det kan erhålla och returnera resultatet utan att bearbeta transaktionen igen.
Ett program kan pausa alla transaktioner som är associerade med en specifik konversationsreferens genom att ange referensen och flaggan EC_DISABLE i ett anrop till DdeEnableCallback. Genom att ange en NULL- handtag kan ett program pausa alla transaktioner för alla konversationer.
När en konversation har pausats sparar DDEML transaktioner för konversationen i en transaktionskö. När programmet återaktivera konversationen tar DDEML bort de sparade transaktionerna från kön och skickar varje transaktion till rätt återanropsfunktion. Kapaciteten i transaktionskö är stor, men ett program bör återaktivera en pausad konversation så snart som möjligt för att undvika att förlora transaktioner.
Ett program kan återuppta den vanliga transaktionsbearbetningen genom att ange flaggan EC_ENABLEALL i DdeEnableCallback. För ett mer kontrollerat återupptagande av transaktionsbearbetningen kan programmet ange flaggan EC_ENABLEONE. Den här flaggan tar bort en transaktion från transaktionsköen och skickar den till lämplig återanropsfunktion. när transaktionen har bearbetats inaktiveras alla konversationer igen.
Om flaggan EC_ENABLEONE och ett konversationshandtag anges i anropet till DdeEnableCallbackblockeras bara konversationen när transaktionen har bearbetats. Om en NULL- konversationshandtag har angetts blockeras alla konversationer efter att en transaktion har bearbetats i en konversation.
Transaktionsklasser
DDEML har fyra klasser av transaktioner. Varje klass identifieras av en konstant som börjar med prefixet XCLASS_. Klasserna definieras i DDEML-huvudfilen. Klassvärdet kombineras med värdet av transaktionstyp och skickas till DDE-återanropsfunktionen i det mottagande programmet.
En transaktionsklass avgör det returvärde som en återanropsfunktion förväntas returnera om den bearbetar transaktionen. Följande returvärden och transaktionstyper är associerade med var och en av de fyra transaktionsklasserna.
Klass | Returvärde | Transaktion |
---|---|---|
XCLASS_BOOL | TRUE eller FALSE |
XTYP_ADVSTART XTYP_CONNECT |
XCLASS_DATA | Ett datahandtag, CBR_BLOCK returnerar kod eller NULL- |
XTYP_ADVREQ XTYP_REQUEST XTYP_WILDCONNECT |
XCLASS_FLAGS | En transaktionsflagga: DDE_FACK, DDE_FBUSY eller DDE_FNOTPROCESSED |
XTYP_ADVDATA XTYP_EXECUTE XTYP_POKE |
XCLASS_NOTIFICATION | Ingen |
XTYP_ADVSTOP XTYP_CONNECT_CONFIRM XTYP_DISCONNECT XTYP_ERROR XTYP_REGISTER XTYP_UNREGISTER XTYP_XACT_COMPLETE |
Transaktionstyper
Varje DDE-transaktionstyp har en mottagare och en associerad aktivitet som gör att DDEML genererar varje typ.
Transaktionstyp | Mottagare | Orsak |
---|---|---|
XTYP_ADVDATA | Klient | En server svarade på en XTYP_ADVREQ transaktion genom att returnera ett datahandtag. |
XTYP_ADVREQ | Server | En server som heter funktionen DdePostAdvise som anger att värdet för ett dataobjekt i en rådgivningsloop har ändrats. |
XTYP_ADVSTART | Server | En klient angav XTYP_ADVSTART transaktionstyp i ett anrop till funktionen DdeClientTransaction. |
XTYP_ADVSTOP | Server | En klient angav XTYP_ADVSTOP transaktionstyp i ett anrop till DdeClientTransaction. |
XTYP_CONNECT | Server | En klient som heter funktionen DdeConnect och angav ett tjänstnamn och ämnesnamn som stöds av servern. |
XTYP_CONNECT_CONFIRM | Server | Servern returnerade TRUE- som svar på en XTYP_CONNECT eller XTYP_WILDCONNECT transaktion. |
XTYP_DISCONNECT | Klient/server | En partner i en konversation som kallas funktionen DdeDisconnect, vilket gör att båda partnerna får den här transaktionen. |
XTYP_ERROR | Klient/server | Ett kritiskt fel har inträffat. DDEML kanske inte har tillräckligt med resurser för att fortsätta. |
XTYP_EXECUTE | Server | En klient angav XTYP_EXECUTE transaktionstyp i ett anrop till DdeClientTransaction. |
XTYP_MONITOR | DDE-övervakningsprogram | En DDE-händelse inträffade i systemet. Mer information om DDE-övervakningsprogram finns i Övervakningsprogram. |
XTYP_POKE | Server | En klient angav XTYP_POKE transaktionstyp i ett anrop till DdeClientTransaction. |
XTYP_REGISTER | Klient/server | Ett serverprogram använde funktionen DdeNameService för att registrera ett tjänstnamn. |
XTYP_REQUEST | Server | En klient angav XTYP_REQUEST transaktionstyp i ett anrop till DdeClientTransaction. |
XTYP_UNREGISTER | Klient/server | Ett serverprogram som används DdeNameService för att avregistrera ett tjänstnamn. |
XTYP_WILDCONNECT | Server | En klient som heter funktionen DdeConnect eller DdeConnectList och anger NULL- för tjänstnamnet, ämnesnamnet eller båda. |
XTYP_XACT_COMPLETE | Klient | En asynkron transaktion som skickades när klienten angav flaggan TIMEOUT_ASYNC i ett anrop till DdeClientTransaction, har slutförts. |