Ta bort en provider
När WMI är klar med en leverantör, avlägsnas leverantören från minnet. Den främsta orsaken till att WMI tar bort en provider är att spara systemresurser. Därför måste du lägga till kod som gör att WMI kan lossa din leverantör på ett effektivt sätt. Det tar från intervallet som anges i cachekontrollen till två gånger det intervallet för WMI att avlasta en leverantör.
WMI avlastar en provider på något av följande sätt:
- Ta bort en leverantör när leverantören har slutfört de uppgifter som har getts till den.
- Ta snabbt bort alla leverantörer när användaren stänger av systemet. Observera att WMI avlägsnar processleverantörer när WMI-tjänsten stängs av via kommandoraden.
Även om det första scenariot är vanligare måste du skriva till din leverantör för båda alternativen.
Följande avsnitt beskrivs i det här avsnittet:
- Lastar av en inaktiv Tjänsteleverantör
- Åtkomst till inaktivitetstiden för en leverantör
- Avlasta en provider som också är en WMI-klient
- avlasta en provider vid avstängning
- Relaterade ämnen
Avlasta en inaktiv provider
WMI utför följande åtgärder när en inaktiv leverantör avlastas:
Avgör om providern är inaktiv.
WMI använder egenskapen ClearAfter för att avgöra hur länge en leverantör kan vara inaktiv innan leverantören avlastas. Mer information finns i Åtkomst till inaktivitetstiden för en leverantör.
Anropar providerns metod Release.
Om leverantören var en ren leverantör tar Release helt och hållet bort leverantören från operativt minne. En icke-pure-provider kan dock fortsätta att köras efter WMI-anrop Release.
Åtkomst till vilotid för en leverantör
Den minsta tiden som en provider förblir aktiv bestäms av egenskapen ClearAfter. Du hittar ClearAfter i instanser av klasser som härleds från WMI-systemklassen __CacheControl i namnområdet \root.
I följande lista beskrivs de klasser som härleds från __CacheControl, som styr providerns avlastning:
- __EventConsumerProviderCacheControl
- __EventProviderCacheControl
- __EventSinkCacheControl
- __ObjectProviderCacheControl
- __PropertyProviderCacheControl
Du kan ändra den minsta tid som WMI tillåter att en provider förblir inaktiv genom att redigera egenskapen ClearAfter i cachekontrollinstansen för en viss typ av provider. Om du till exempel vill begränsa hur lång tid en egenskapsprovider kan vara inaktiv redigerar du egenskapen ClearAfter för en __PropertyProviderCacheControl-instans i namnområdet \root.
Avlasta en provider som också är en WMI-klient
Leverantören kan behöva förbli en klient för WMI när den har slutfört de providerfunktioner som den anropades för att utföra. En push-provider kan till exempel behöva utfärda frågor till WMI. För mer information, se om att fastställa status för push eller pull. I det här fallet ska egenskapen Pure för den __Win32Provider instans som representerar providern anges till TRUE-. Om egenskapen Pure är inställd på FALSE, förbereder providern sig för att frigöra resurser genom att anropa IUnknown::Release vid alla kvarstående gränssnittspunkter när WMI anropar Release-metoden för det primära gränssnittet. Mer information finns i avsnittet Anmärkningar i __Win32Provider.
Följande procedur beskriver hur du implementerar en versionsmetod för providerns primära gränssnitt.
Att avlasta en leverantör
Släpp alla gränssnittspekare mot WMI när WMI anropar metoden Release för providerns primära gränssnitt.
Vanligtvis innehåller en provider pekare till IWbemServices och IWbemContext gränssnitt som tillhandahålls i IWbemProviderInit::Initiera.
Om egenskapen Pure i den associerade __Win32Provider-instansen är inställd på FALSE-kan providern övergå till rollen som klientprogram efter WMI-anrop Release. WMI kan dock inte ta bort en provider som fungerar som ett klientsystem, vilket ökar systemets omkostnader.
En leverantör med Pure inställd på TRUE existerar endast för att hantera förfrågningar. Därför kan den här typen av leverantör inte ta på sig rollen som ett klientprogram, och WMI kan avlägsna den.
Avlasta en provider under nedstängning
Under normala omständigheter kan WMI korrekt frånkoppla leverantören med hjälp av riktlinjerna i Avlastning av en leverantör som också är en WMI-klient. Du kan dock stöta på situationer där WMI inte kan initiera normala avlastningsprocedurer, till exempel när användaren väljer att stänga av systemet. Genom att använda en transaktionsmodell för datalagring och implementera en bra rensningsstrategi, kan du säkerställa att leverantören är korrekt avlastad.
Användaren kan när som helst stoppa WMI. I en sådan situation avlastar WMI inte några leverantörer eller anropar DllCanUnloadNow startpunkt på någon i-process leverantör. Om en in-process-provider är mitt i ett metodanrop vid tidpunkten för avstängningen kan det hända att WMI avslutar den körande tråden mitt i anropet. I detta fall anropar WMI inte rutiner som normalt hanterar rensning, till exempel en objektförstörare. Som mest anropar WMI endast DllMain.
När operativsystemet stänger av WMI frigör systemet automatiskt allt minne som allokerats till en in-process-leverantör. Operativsystemet stänger även de flesta resurser som innehas av providern, till exempel filhandtag, fönsterhandtag och så vidare. Providern behöver inte vidta några specifika åtgärder för att detta ska ske.
Eftersom WMI kan stängas av mitt i ett anrop bör en provider inte lämna datakällor i ett inkonsekvent tillstånd. Att lämna dina data i ett inkonsekvent tillstånd utgör inget problem för leverantörer med skrivskydd. Leverantörer med skrivfunktioner kanske dock vill implementera någon form av transaktionsmodell för att tillåta en säker återställning efter en plötslig avslutning.
Även om operativsystemet kan frigöra vissa allmänna systemresurser släpper systemet inte automatiskt alla resurser. Operativsystemet kanske till exempel inte släpper ut en socket eller en databasanslutning. I stället kan providern behöva rensa sådana resurser manuellt. För att undvika dessa problem kan du antingen implementera din leverantör utanför processen eller lägga till rensningskod.
Den enklaste lösningen är att implementera din leverantör utanför processen. En leverantör utanför processen avbryts inte när WMI stängs av, även om WMI släpper leverantören efter en COM-timeout. Leverantörer för vilka problem med rensning och avslutnings robusthet är viktigare än prestanda kan vara out-of-process.
Om du måste placera rensningskoden i tjänsteleverantören har du två alternativ. En plats där du kan utföra den här typen av rensning är DllMain, DLL-startpunkten som operativsystemet anropar när DLL:en tas bort. Rensningskoden kan läggas till direkt i DllMainoch köra den som svar på DLL_PROCESS_DETACH. Att implementera rensningskod i DllMain kan vara något svårt att ordna, särskilt i programmeringsmiljöer som MFC eller ATL. För mer information, se artikeln Microsoft Knowledge Base Q148791, "How to Provide Your Own DllMain in an MFC Regular DLL." (Den här resursen kanske inte är tillgänglig på vissa språk och i vissa länder eller regioner.)
Alternativt kan du placera rensningskoden i destruktorn för en global klass. Mer information finns i Ta bort en provider. Windows-operativsystemet allokerar inte globala objekt på heap. I stället anropar operativsystemet destruktorer vid DLL-avlastning.
Följande är en enkel rensningsprocedur som kan passa in i ett globalt objekt för WMI.
class CMyCleanup
{
~CMyCleanup()
{
CloseHandle(m_hOpenFile);
CloseDatabaseConnection(g_hDatabase);
}
} g_Cleanup;
Det finns många begränsningar för vad som kan göras i rensningskoden med någon av metoderna. Till exempel kan varken trådar eller DLL:er som inte är implicit länkade nås på något sätt. Dessutom kan du inte göra COM-anrop under några omständigheter.
Relaterade ämnen