Share via


Synkronisera data för multitrådning

När flera trådar kan anropa egenskaperna och metoderna för ett enskilt objekt är det viktigt att dessa anrop synkroniseras. Annars kan en tråd avbryta vad en annan tråd gör och objektet kan lämnas i ett ogiltigt tillstånd. En klass vars medlemmar skyddas mot sådana avbrott kallas trådsäker.

.NET innehåller flera strategier för att synkronisera åtkomst till instanser och statiska medlemmar:

Den vanliga språkkörningen tillhandahåller en trådmodell där klasser delas in i ett antal kategorier som kan synkroniseras på olika sätt beroende på kraven. I följande tabell visas vilket synkroniseringsstöd som ges för fält och metoder med en viss synkroniseringskategori.

Kategori Globala fält Statiska fält Statiska metoder Instansfält Instansmetoder Specifika kodblock
Ingen synkronisering Nej Nej Nej Nej Nej Nej
Synkroniserad kontext Nej Nej Nej Ja Ja Nej
Synkroniserade kodregioner Nej Nej Endast om markerat Nej Endast om markerat Endast om markerat
Manuell synkronisering Manuell Manuell Manuell Manuell Manuell Manuell

Ingen synkronisering

Detta är standardvärdet för objekt. Alla trådar kan komma åt valfri metod eller fält när som helst. Endast en tråd i taget bör komma åt dessa objekt.

Manuell synkronisering

.NET-klassbiblioteket innehåller ett antal klasser för synkronisering av trådar. Se Översikt över synkroniseringspri primitiver.

Synkroniserade kodregioner

Du kan använda nyckelordet Monitor klass eller kompilator för att synkronisera kodblock, instansmetoder och statiska metoder. Det finns inget stöd för synkroniserade statiska fält.

Både Visual Basic och C# stöder märkning av kodblock med ett visst språknyckelord, -instruktionen lock i C# eller -instruktionen SyncLock i Visual Basic. När koden körs av en tråd görs ett försök att hämta låset. Om låset redan har hämtats av en annan tråd blockerar tråden tills låset blir tillgängligt. När tråden avslutar det synkroniserade kodblocket släpps låset, oavsett hur tråden avslutar blocket.

Kommentar

Från och med C# 13 identifierar instruktionen lock om det låsta objektet är en instans av System.Threading.Lock och använder EnterScope metoden för att skapa en synkroniserad region. , locknär målet inte är en Lock instans, och SyncLock -instruktioner implementeras med och Monitor.EnterMonitor.Exit, så att andra metoder Monitor för kan användas tillsammans med dem i den synkroniserade regionen.

Du kan också dekorera en metod med värdet MethodImplAttributeMethodImplOptions.Synchronized, som har samma effekt som att använda Monitor eller något av kompilatornyckelorden för att låsa hela metodens brödtext.

Thread.Interrupt kan användas för att bryta ut en tråd från blockeringsåtgärder som att vänta på åtkomst till en synkroniserad kodregion. Thread.Interrupt används också för att bryta trådar ur åtgärder som Thread.Sleep.

Viktigt!

Lås inte typen , dvs typeof(MyType) . i C#, GetType(MyType) i Visual Basic eller MyType::typeid I C++, för att skydda static metoder (Shared metoder i Visual Basic). Använd ett privat statiskt objekt i stället. På samma sätt ska du inte använda this i C# (Me i Visual Basic) för att låsa instansmetoder. Använd ett privat objekt i stället. En klass eller instans kan låsas av annan kod än din egen, vilket kan orsaka dödlägen eller prestandaproblem.

Stöd för kompilator

Både Visual Basic och C# stöder ett språknyckelord som använder Monitor.Enter och Monitor.Exit för att låsa objektet. Visual Basic stöder SyncLock-instruktionen. C# stöder lås-instruktionen.

I båda fallen, om ett undantag utlöses i kodblocket, frigörs låset som hämtas av låset eller SyncLock automatiskt. Kompilatorerna C# och Visual Basic genererar ett försök/att slutligen blockera med Monitor.Enter i början av försöket och Monitor.Exit i det sista blocket. Om ett undantag utlöses i låset eller SyncLock-blocket körs slutligen hanteraren så att du kan utföra rensningsarbete.

Synkroniserad kontext

Endast i .NET Framework- och Xamarin-program kan du använda SynchronizationAttribute på alla ContextBoundObject för att synkronisera alla instansmetoder och fält. Alla objekt i samma kontextdomän delar samma lås. Flera trådar kan komma åt metoderna och fälten, men endast en enda tråd tillåts samtidigt.

Se även