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.
.NET innehåller en mängd olika typer som du kan använda för att synkronisera åtkomst till en delad resurs eller samordna trådinteraktion.
Viktigt!
Använd samma primitiva synkroniseringsinstans för att skydda åtkomsten till en delad resurs. Om du använder olika synkroniserings primitiva instanser för att skydda samma resurs kringgår du det skydd som tillhandahålls av en synkroniseringsprimett.
WaitHandle-klass och enkla synkroniseringstyper
Flera .NET-synkroniseringsprimitiver härleds från klassen System.Threading.WaitHandle, som kapslar in ett inbyggt operativsystems synkroniseringshandtag och använder en signalmekanism för trådinteraktioner. Dessa klasser omfattar:
- System.Threading.Mutex, som ger exklusiv åtkomst till en delad resurs. Tillståndet för en mutex signaleras när ingen tråd äger den.
- System.Threading.Semaphore, som begränsar antalet trådar som kan komma åt en delad resurs eller en resurspool samtidigt. Tillståndet för en semafor är inställt på att signaleras när dess antal är större än noll och nonsignaled när dess antal är noll.
- System.Threading.EventWaitHandle, som representerar en trådsynkroniseringshändelse och kan vara antingen i ett signalerat eller osignalat tillstånd.
- System.Threading.AutoResetEvent, som härleds från EventWaitHandle och, när den signaleras, återställs automatiskt till ett osignalat tillstånd efter att en enda väntande tråd släppts.
- System.Threading.ManualResetEvent, som härleds från EventWaitHandle och, när den signaleras, förblir i ett signalerat tillstånd tills Reset metoden anropas.
I .NET Framework, eftersom WaitHandle härleds från System.MarshalByRefObject, kan dessa typer användas för att synkronisera aktiviteter för trådar över programdomängränser.
I .NET Framework, .NET Core och .NET 5+, kan vissa av dessa typer representera namngivna systemsynkroniseringshandtag, som är synliga i hela operativsystemet och kan användas för synkronisering mellan processer:
- Mutex
- Semaphore (i Windows)
- EventWaitHandle (i Windows)
Mer information finns i API-referensen WaitHandle .
Enkla synkroniseringstyper förlitar sig inte på underliggande operativsystemhandtag och ger vanligtvis bättre prestanda. De kan dock inte användas för synkronisering mellan processer. Använd dessa typer för trådsynkronisering i ett program.
Vissa av dessa typer är alternativ till de typer som härleds från WaitHandle. Är till exempel SemaphoreSlim ett enkelt alternativ till Semaphore.
Synkronisering av åtkomst till en delad resurs
.NET tillhandahåller ett antal synkroniseringsprimitiver för att styra åtkomsten till en delad resurs av flera trådar.
Övervaka klass
Klassen System.Threading.Monitor ger ömsesidigt exklusiv åtkomst till en delad resurs genom att hämta eller frigöra ett lås på objektet som identifierar resursen. Medan ett lås hålls, kan tråden som har låset återigen ta och släppa låset. Alla andra trådar blockeras från att hämta låset Monitor.Enter och metoden väntar tills låset släpps. Metoden Enter låser upp ett frisläppt lås. Du kan också använda Monitor.TryEnter metoden för att ange hur lång tid en tråd försöker hämta ett lås under. Eftersom Monitor-klassen har trådtillhörighet måste tråden som skaffade ett lås frigöra låset genom att anropa metoden Monitor.Exit.
Du kan samordna interaktionen mellan trådar som erhåller ett lås på samma objekt genom att använda metoderna Monitor.Wait, Monitor.Pulse och Monitor.PulseAll.
Mer information finns i API-referensen Monitor .
Anmärkning
Använd låssatsen i C# och SyncLock-instruktionen i Visual Basic för att synkronisera åtkomst till en delad resurs i stället för att använda Monitor klassen direkt. Dessa instruktioner implementeras med metoderna Enter och Exit och ett try…finally
block för att säkerställa att det förvärvade låset alltid släpps.
Mutex-klass
Klassen System.Threading.Mutex , till exempel Monitor, ger exklusiv åtkomst till en delad resurs. Använd en av överlagringarna av metoden Mutex.WaitOne för att begära ägarskap av en mutex. Likt Monitor har Mutex trådtillhörighet och tråden som skaffade en mutex måste frigöra den genom att anropa metoden Mutex.ReleaseMutex.
Monitor Till skillnad från Mutexkan klassen användas för synkronisering mellan processer. För att göra det använder du en namngiven mutex, som är synlig i hela operativsystemet. Om du vill skapa en namngiven mutex-instans använder du en Mutex-konstruktor som anger ett namn. Du kan också anropa Mutex.OpenExisting-metoden för att öppna en befintlig namngiven system-mutex.
Mer information finns i artikeln Mutexes och API-referensen Mutex .
SpinLock-struktur
Strukturen System.Threading.SpinLock , till exempel Monitor, ger exklusiv åtkomst till en delad resurs baserat på tillgängligheten för ett lås. När SpinLock försöker hämta ett lås som inte är tillgängligt väntar det i en slinga och kontrollerar det upprepade gånger tills låset blir tillgängligt.
Mer information om fördelarna och nackdelarna med att använda spinnlås finns i SpinLock-artikeln och API-referensen SpinLock .
ReaderWriterLockSlim-klass
Klassen System.Threading.ReaderWriterLockSlim ger exklusiv åtkomst till en delad resurs för skrivning och tillåter flera trådar att komma åt resursen samtidigt för läsning. Du kanske vill använda ReaderWriterLockSlim för att synkronisera åtkomst till en delad datastruktur som stöder trådsäkra läsåtgärder, men som kräver exklusiv åtkomst för att utföra skrivåtgärder. När en tråd begär exklusiv åtkomst (till exempel genom att anropa ReaderWriterLockSlim.EnterWriteLock metoden) blockeras efterföljande läsar- och skrivarbegäranden tills alla befintliga läsare har avslutat låset och skrivaren har angett och avslutat låset.
Mer information finns i API-referensen ReaderWriterLockSlim .
Semafor- och SemaphoreSlim-klasser
Klasserna System.Threading.Semaphore och System.Threading.SemaphoreSlim begränsar antalet trådar som kan komma åt en delad resurs eller en resurspool samtidigt. Ytterligare trådar som begär resursen väntar tills någon tråd släpper semaforen. Eftersom semaforen inte har trådtillhörighet kan en tråd hämta semaforen och en annan kan släppa den.
SemaphoreSlim är ett enkelt alternativ till Semaphore och kan endast användas för synkronisering inom en enda processgräns.
I Windows kan du använda Semaphore för synkronisering mellan processer. För att göra det skapar du en Semaphore instans som representerar en namngiven systemsemafor med hjälp av någon av de semaforkonstruktorer som anger ett namn eller en Semaphore.OpenExisting metod. SemaphoreSlim stöder inte namngivna systemsemaforer.
Mer information finns i artikeln Semaphore och SemaphoreSlim och API-referensen Semaphore eller SemaphoreSlim .
Trådinteraktion eller signalering
Trådinteraktion (eller trådsignalering) innebär att en tråd måste vänta på meddelande, eller en signal, från en eller flera trådar för att kunna fortsätta. Om tråd A till exempel anropar Thread.Join-metoden för tråd B blockeras tråd A tills tråd B har avslutats. Synkroniseringens primitiver som beskrivs i föregående avsnitt ger en annan mekanism för signalering: genom att frigöra ett lås meddelar en tråd en annan tråd att den kan fortsätta genom att hämta låset.
I det här avsnittet beskrivs ytterligare signalkonstruktioner som tillhandahålls av .NET.
Klasser för EventWaitHandle, AutoResetEvent, ManualResetEvent och ManualResetEventSlim
Klassen System.Threading.EventWaitHandle representerar en trådsynkroniseringshändelse.
En synkroniseringshändelse kan antingen vara i ett osignalat eller signalerat tillstånd. När tillståndet för en händelse är osignalat blockeras en tråd som anropar händelsens WaitOne överbelastning tills en händelse signaleras. Metoden EventWaitHandle.Set anger tillståndet för en händelse till signalerad.
Beteendet för en EventWaitHandle som har signalerats beror på dess återställningsläge:
- En EventWaitHandle som skapas med EventResetMode.AutoReset flaggan återställs automatiskt efter att en enda väntande tråd har släppts. Det är som ett vändkors som bara tillåter en tråd genom varje gång den signaleras. Klassen System.Threading.AutoResetEvent , som härleds från EventWaitHandle, representerar det beteendet.
- En EventWaitHandle skapad med EventResetMode.ManualReset flaggan förblir signalerad tills dess Reset metod anropas. Det är som en grind som är stängd tills den signaleras och sedan förblir öppen tills någon stänger den. Klassen System.Threading.ManualResetEvent , som härleds från EventWaitHandle, representerar det beteendet. Klassen System.Threading.ManualResetEventSlim är ett enkelt alternativ till ManualResetEvent.
I Windows kan du använda EventWaitHandle för synkronisering mellan processer. För att göra det skapar du en EventWaitHandle instans som representerar en namngiven systemsynkroniseringshändelse med hjälp av någon av EventWaitHandle-konstruktorerna som anger ett namn eller en EventWaitHandle.OpenExisting metod.
Mer information finns i artikeln EventWaitHandle . Api-referensen finns i EventWaitHandle, AutoResetEvent, ManualResetEventoch ManualResetEventSlim.
CountdownEvent-klass
Klassen System.Threading.CountdownEvent representerar en händelse som anges när antalet är noll. Medan CountdownEvent.CurrentCount är större än noll blockeras en tråd som anropar CountdownEvent.Wait . Anropa CountdownEvent.Signal för att minska antalet händelser.
Till skillnad från ManualResetEvent eller ManualResetEventSlim, som du kan använda för att avblockera flera trådar med en signal från en tråd, kan du använda CountdownEvent för att avblockera en eller flera trådar med signaler från flera trådar.
Mer information finns i artikeln CountdownEvent och API-referensen CountdownEvent .
Barriärklass
Klassen System.Threading.Barrier representerar en trådkörningsbarriär. En tråd som anropar Barrier.SignalAndWait metoden signalerar att den nått barriären och väntar tills andra deltagartrådar når barriären. När alla deltagartrådar når barriären fortsätter de och barriären återställs och kan användas igen.
Du kan använda Barrier när en eller flera trådar kräver resultatet av andra trådar innan du fortsätter till nästa beräkningsfas.
Mer information finns i artikeln Barriär och API-referensen Barrier .
Sammanlåst klass
Klassen System.Threading.Interlocked innehåller statiska metoder som utför enkla atomiska åtgärder på en variabel. Dessa atomiska åtgärder omfattar addition, inkrement och minskning, utbyte och villkorligt utbyte som är beroende av en jämförelse och läsåtgärd av ett 64-bitars heltalsvärde.
Mer information finns i API-referensen Interlocked .
SpinWait-struktur
Strukturen System.Threading.SpinWait ger stöd för spinnbaserad väntan. Du kanske vill använda den när en tråd måste vänta på att en händelse ska signaleras eller ett villkor uppfylls, men när den faktiska väntetiden förväntas vara mindre än den väntetid som krävs med hjälp av ett väntehandtag eller genom att på annat sätt blockera tråden. Med hjälp av SpinWait kan du ange en kort tidsperiod för att snurra medan du väntar och sedan avbryta (till exempel genom att vänta eller sova) endast om villkoret inte har uppfyllts under den angivna tiden.
Mer information finns i spinwait-artikeln och API-referensen SpinWait .