Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Klassen System.Threading.Semaphore representerar en namngiven (systemomfattande) eller lokal semafor. Det är en tunn omslutning runt Win32-semaforobjektet. Win32-semaforer är räknande semaforer, som kan användas för att styra åtkomsten till en pool med resurser.
Klassen SemaphoreSlim representerar en lätt, snabb semafor som kan användas för att vänta i en enda process när väntetiderna förväntas vara mycket korta. SemaphoreSlim förlitar sig så mycket som möjligt på synkronisering primitiver som tillhandahålls av common language runtime (CLR). Det ger dock också lättinitierade, kernelbaserade väntehandtag efter behov för att stödja väntan på flera semaforer. SemaphoreSlim stöder också användning av avbokningstoken, men det stöder inte namngivna semaforer eller användning av en väntesignal för synkronisering.
Hantera en begränsad resurs
Trådar går in i semaforen genom att anropa WaitOne-metoden, som ärvs från WaitHandle-klassen, i fallet med ett System.Threading.Semaphore objekt, eller SemaphoreSlim.Wait- eller SemaphoreSlim.WaitAsync-metoden, i fallet med ett SemaphoreSlim objekt. När anropet returnerar minskas räknaren på semaforen. När en tråd begär post och antalet är noll blockeras tråden. När trådar släpper semaforen genom att anropa metoden Semaphore.Release eller SemaphoreSlim.Release tillåts blockerade trådar komma in. Det finns ingen garanterad ordning, till exempel först in, först ut (FIFO) eller sista in, först ut (LIFO), för blockerade trådar för att komma in i semaforen.
En tråd kan ange semafor flera gånger genom att anropa System.Threading.Semaphore objektets WaitOne metod eller SemaphoreSlim objektets Wait metod upprepade gånger. För att frigöra semaforen kan tråden anropa metoden Semaphore.Release() eller SemaphoreSlim.Release() samma antal gånger, eller anropa metodöverlagringen Semaphore.Release(Int32) eller SemaphoreSlim.Release(Int32) och ange antalet poster som ska frigöras.
Semaforer och trådidentitet
De två semafortyperna tillämpar inte trådidentitet på anrop till WaitOnemetoderna , Wait, Releaseoch SemaphoreSlim.Release . Ett vanligt användningsscenario för semaforer omfattar till exempel en producenttråd och en konsumenttråd, där en tråd alltid ökar antalet semaforer och den andra alltid minskar den.
Det är programmerarens ansvar att se till att en tråd inte släpper ut semaforen för många gånger. Anta till exempel att en semafor har ett maximalt antal av två, och att tråd A och tråd B båda går in i semaforen. Om ett programmeringsfel i tråd B gör att det anropas Release två gånger lyckas båda anropen. Räknaren på semaforen är full, och när tråd A så småningom anropar Release, kastas en SemaphoreFullException.
Med namnet Semaphores
Windows-operativsystemet tillåter att semaforer har namn. En namngiven semafor är systemomfattande. När den namngivna semaforen har skapats är den alltså synlig för alla trådar i alla processer. Därför kan namngivna semafor användas för att synkronisera både processers och trådars aktiviteter.
Du kan skapa ett Semaphore objekt som representerar en namngiven systemsemafor med hjälp av någon av konstruktorerna som anger ett namn.
Anmärkning
Eftersom namngivna semaphores är systemomfattande är det möjligt att ha flera Semaphore objekt som representerar samma namngivna semafor. Varje gång du anropar en konstruktor eller Semaphore.OpenExisting metod skapas ett nytt Semaphore objekt. Om du anger samma namn upprepade gånger skapas flera objekt som representerar samma namngivna semafor.
Var försiktig när du använder namngivna semaforer. Eftersom de är systemomfattande kan en annan process som använder samma namn ange din semafor oväntat. Skadlig kod som körs på samma dator kan använda detta som grund för en överbelastningsattack.
Använd åtkomstkontrollsäkerhet för att skydda ett Semaphore objekt som representerar en namngiven semafor, helst med hjälp av en konstruktor som anger ett System.Security.AccessControl.SemaphoreSecurity objekt. Du kan också använda åtkomstkontrollsäkerhet med hjälp av Semaphore.SetAccessControl metoden, men detta lämnar ett säkerhetsfönster mellan den tid då semaforen skapas och den tid det skyddas. Att skydda semaforer med åtkomstkontrollsäkerhet hjälper till att förhindra skadliga attacker, men löser inte problemet med oavsiktliga namnkollisioner.