Kommentar
Å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 styr åtkomsten till en resurspool.
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 bli korta. Under spin-wait-fasen snurrar processorn aktivt – den är inte inaktiv. Hur kort "kort" måste vara beror på vilken typ av väntan: om trådar konkurrerar om CPU-resurser förbrukar den snurrande tråden CPU-tid, så väntan bör vara mycket kort, mätt i mikrosekunder. Om väntetiden är för en icke-CPU-bunden resurs (till exempel I/O) är spin-wait-kostnaden mindre oroande och den acceptabla väntan kan vara något längre, mätt i millisekunder. När väntetiderna är oförutsägbara eller förväntas vara betydande använder du System.Threading.Semaphore i stället, vilket inte snurrar. 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 även användning av annulleringstokens, men erbjuder inte stöd för namngivna semaforer eller användning av en väntsignal för synkronisering.
Hantera en begränsad resurs
Trådar går in i semaforen genom att anropa olika metoder beroende på semaforens typ. För ett System.Threading.Semaphore objekt anropar du WaitOne metoden (ärvd från WaitHandle). Anropa SemaphoreSlim.Wait- eller SemaphoreSlim.WaitAsync-metoden för 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 Semaphore.Release metoden eller SemaphoreSlim.Release kan blockerade trådar komma in. Ingen garanterad ordning, till exempel först-in, först-ut (FIFO) eller sista-in, första-ut (LIFO), styr vilken blockerad tråd som kommer in i semaforen näst.
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. Om du vill släppa semaforen anropar du metoden Semaphore.Release() eller SemaphoreSlim.Release() samma antal gånger som tråden anropats. Alternativt kan du anropa överlagringen Semaphore.Release(Int32) eller SemaphoreSlim.Release(Int32) och specificera antalet poster som ska släppas.
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.
Se till att en tråd inte släpper 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.
Namngivna semaforer
Windows-operativsystemet tillåter att semaforer har namn. En namngiven semafor är systemomfattande – när den har skapats är den synlig för alla trådar i alla processer. Namngivna semaforer kan därför synkronisera både processers och trådars aktiviteter.
Skapa ett Semaphore objekt som representerar en namngiven systemsemafor med hjälp av någon av konstruktorerna som anger ett namn.
Viktigt!
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 på systemnivå kan en annan process som använder samma namn oväntat komma in i din semafor. 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 Semaphore.SetAccessControl av metoden, men detta lämnar ett säkerhetsfönster mellan tiden då semaforen skapas och den tid den skyddas. Att skydda semaforer med åtkomstkontrollsäkerhet hjälper till att förhindra skadliga attacker, men löser inte problemet med oavsiktliga namnkollisioner.