Een provider ontladen
Nadat WMI klaar is met een provider, laadt het de provider uit het geheugen. De belangrijkste reden dat WMI een provider ontlaadt, is het besparen van systeembronnen. Daarom moet u code toevoegen waarmee WMI uw provider op een efficiënte manier kan ontladen. Het kan enige tijd in beslag nemen, variërend van het interval dat is opgegeven in het cachebeheer tot twee keer dat interval, voordat WMI een provider ontlaadt.
WMI verwijdert een provider op een van de volgende manieren:
- Verwijder een provider nadat de provider de taken heeft voltooid die eraan zijn gegeven.
- Verwijder snel alle providers wanneer de gebruiker het systeem afsluit. WMI verwijdert in-proces providers wanneer de WMI-service wordt afgesloten vanaf de opdrachtregelinterface.
Hoewel het eerste scenario vaker voorkomt, moet u contact opnemen met uw provider voor beide mogelijkheden.
In dit onderwerp worden de volgende secties besproken:
- Het lossen van een niet-actieve provider
- toegang tot de niet-actieve tijd voor een provider
- Het deactiveren van een provider die tevens een WMI-client is
- Een provider ontladen tijdens afsluiten
- Verwante onderwerpen
Het ontladen van een inactieve provider.
WMI voert de volgende acties uit wanneer een niet-actieve provider wordt ontladen.
Bepaalt of de provider niet actief is.
WMI gebruikt de eigenschap ClearAfter om te bepalen hoe lang een provider inactief mag blijven voordat deze provider wordt ontladen. Zie Toegang tot de niet-actieve tijd voor een providervoor meer informatie.
Roept de Release--methode van de provider aan.
Als de provider een pure provider was, verwijdert Release de provider volledig uit het actieve geheugen. Een niet-zuivere provider kan echter blijven draaien na WMI-aanroepen Release.
Toegang tot de niet-actieve tijd voor een provider
De minimale tijdsduur die een provider actief blijft, wordt bepaald door de eigenschap ClearAfter. U vindt ClearAfter in instanties van klassen die zijn afgeleid van de WMI-systeemklasse __CacheControl in de \root-naamruimte.
In de volgende lijst worden de klassen beschreven die zijn afgeleid van __CacheControl, waarmee de provider wordt ontladen.
- __EventConsumerProviderCacheControl
- __EventProviderCacheControl
- __EventSinkCacheControl
- __ObjectProviderCacheControl
- __PropertyProviderCacheControl
U kunt de minimale tijdsduur die WMI toestaat dat een provider inactief mag blijven, wijzigen door de eigenschap ClearAfter te bewerken in het cachebeheerexemplaar voor een specifiek type provider. Als u bijvoorbeeld wilt beperken hoe lang een eigenschapsprovider niet actief kan blijven, bewerkt u de eigenschap ClearAfter van een __PropertyProviderCacheControl exemplaar in de \root-naamruimte.
Een provider lossen die ook een WMI-client is
Uw provider moet mogelijk een client van WMI blijven nadat deze de providerfuncties heeft voltooid die zijn aangeroepen om uit te voeren. Een pushprovider moet bijvoorbeeld mogelijk query's uitgeven aan WMI. Zie Push- of Pull-status bepalenvoor meer informatie. In dit geval moet de eigenschap Pure van het __Win32Provider exemplaar dat de provider vertegenwoordigt, worden ingesteld op TRUE-. Als de eigenschap Pure is ingesteld op FALSE, bereidt de provider zich voor om het laden ongedaan te maken door IUnknown::Release op alle openstaande interfacepunten aan te roepen wanneer WMI de releasemethode van de primaire interface aanroept. Zie de sectie Opmerkingen in __Win32Providervoor meer informatie.
In de volgende procedure wordt beschreven hoe u een releasemethode implementeert voor de primaire interface van uw provider.
Om een provider te ontladen
Laat alle interface-pointers die tegen WMI worden gehouden los wanneer WMI de Release-methode van de primaire interface van uw aanbieder aanroept.
Meestal bevat een provider pointers naar de IWbemServices en IWbemContext interfaces geleverd in IWbemProviderInit::Initialize.
Als de eigenschap Pure in het bijbehorende __Win32Provider exemplaar is ingesteld op FALSE-, kan de provider overstappen op de rol van clienttoepassing nadat WMI Release-heeft aangeroepen. WMI kan echter geen provider die als clientsysteem werkt, ontladen, waardoor de systeemoverhead toeneemt.
Een provider met Pure ingesteld op TRUE bestaat alleen voor serviceaanvragen. Daarom kan dit type provider de rol van een clienttoepassing niet overnemen en kan WMI deze verwijderen.
Een provider lossen tijdens uitschakeling
Onder normale omstandigheden stelt het gebruiken van de richtlijnen in Het correct uitladen van een provider die ook een WMI-client is WMI in staat om uw provider correct uit te laden. U kunt echter situaties tegenkomen waarbij WMI de normale losprocedures niet kan inschakelen, bijvoorbeeld wanneer de gebruiker ervoor kiest om het systeem af te sluiten. Door gebruik te maken van een transactiemodel voor gegevensopslag en door tegelijkertijd een goede opschoonstrategie te implementeren, kunt u ervoor zorgen dat uw provider correct wordt ontladen.
De gebruiker kan WMI op elk gewenst moment stoppen. In een dergelijke situatie ontlaadt WMI geen providers en roept het de DllCanUnloadNow ingangspunt niet aan voor een in-process-provider. Bovendien, als een in-process provider midden in een methodeaanroep zit op het moment van uitschakelen, kan WMI mogelijk de uitvoering van de thread tijdens de aanroep beëindigen. In dit geval roept WMI geen routines aan die normaal gesproken opruimwerkzaamheden uitvoeren, zoals een objectdestructor. WMI roept maximaal DllMain aan.
Wanneer het besturingssysteem WMI afsluit, geeft het systeem automatisch alle geheugen vrij die is toegewezen aan een in-process provider. Het besturingssysteem sluit ook de meeste resources die door de provider worden bewaard, zoals bestandsgrepen, venstergrepen, enzovoort. De provider hoeft geen specifieke actie te ondernemen om dit te laten gebeuren.
Omdat WMI in het midden van een aanroep kan worden afgesloten, mag een provider geen gegevensbronnen in een inconsistente status achterlaten. Uw gegevens in een inconsistente toestand laten staan, is geen probleem voor providers die alleen-lezenmodus gebruiken. Providers met schrijfmogelijkheden willen echter mogelijk een soort transactiemodel implementeren om een veilige terugdraaibewerking mogelijk te maken na een abrupte beëindiging.
Hoewel het besturingssysteem enkele algemene systeembronnen kan vrijgeven, worden niet automatisch alle resources door het systeem vrijgegeven. Het besturingssysteem kan bijvoorbeeld geen socket of databaseverbinding vrijgeven. In plaats daarvan moet de provider dergelijke resources mogelijk handmatig opschonen. Om deze problemen te voorkomen, kunt u uw provider buiten het proces implementeren, of u kunt opschoningscode toevoegen.
De eenvoudigste oplossing is om uw provider buiten het proces te implementeren. Een out-of-process provider wordt niet gedood wanneer WMI wordt afgesloten, hoewel WMI de provider zal vrijgeven na een COM-time-out. Providers voor wie robuustheid bij het opschonen en beëindigen belangrijker is dan prestaties kunnen buiten het proces om werken.
Als u opschooncode in uw provider moet plaatsen, hebt u twee opties. Eén plaats om dit soort opschoning uit te voeren is DllMain, de DLL-ingangspuntfunctie die het besturingssysteem aanroept bij het lossen van de DLL. Opschoningscode kan rechtstreeks worden toegevoegd aan DllMain-, waarbij deze wordt uitgevoerd als reactie op DLL_PROCESS_DETACH. Het implementeren van opschooncode in DllMain kan enigszins moeilijk zijn, vooral in programmeeromgevingen zoals MFC of ATL. Zie het Microsoft Knowledge Base-artikel Q148791, "How to Provide Your Own DllMain in an MFC Regular DLL" voor meer informatie. (Deze resource is mogelijk niet beschikbaar in sommige talen en landen of regio's.)
Een andere mogelijkheid is om de opschooncode in de destructor van een globale klasse te plaatsen. Raadpleeg Unloading a Provider voor meer informatie. Het Windows-besturingssysteem wijst geen globale objecten toe op de heap. In plaats daarvan roept het besturingssysteem de destructors aan tijdens het verwijderen van het DLL-bestand.
Dit is een eenvoudige opschoonprocedure die binnen een globaal object voor WMI past.
class CMyCleanup
{
~CMyCleanup()
{
CloseHandle(m_hOpenFile);
CloseDatabaseConnection(g_hDatabase);
}
} g_Cleanup;
Er zijn veel beperkingen met betrekking tot wat er in de opschooncode kan worden gedaan met beide benaderingen. Zo kunnen threads of DLL's die niet impliciet zijn gekoppeld, op geen enkele manier worden geopend. Verder kunt u geen COM-aanroepen doen onder welke omstandigheden dan ook.
Verwante onderwerpen