Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
deyimi lock belirli bir nesne için karşılıklı dışlama kilidini alır, bir deyim bloğu yürütür ve ardından kilidi serbest bırakır. Kilit tutulurken, kilidi tutan iş parçacığı kilidi birden çok kez alabilir ve serbest bırakabilir. Diğer tüm iş parçacıklarının kilidi almaları engellenir ve kilit serbest bırakılana kadar bekler. deyimi, lock gövdesini zaman içinde en fazla bir iş parçacığının yürütmesini sağlar.
C# dili başvuru belgesi, C# dilinin en son yayımlanan sürümünü gösterir. Ayrıca, yaklaşan dil sürümü için genel önizlemelerdeki özelliklere yönelik ilk belgeleri içerir.
Belgelerde ilk olarak dilin son üç sürümünde veya geçerli genel önizlemelerde sunulan tüm özellikler tanımlanır.
Tavsiye
Bir özelliğin C# dilinde ilk tanıtıldığı zamanları bulmak için C# dil sürümü geçmişi makalesine bakın.
deyimi lock aşağıdaki formu alır:
lock (x)
{
// Your code...
}
Değişken x türündeki System.Threading.Lock bir ifade veya başvuru türüdür. Derleyici bunun türünde System.Threading.Lockolduğunu x biliyorsa, tam olarak şunun eşdeğeridir:
using (x.EnterScope())
{
// Your code...
}
tarafından Lock.EnterScope() döndürülen nesnesi, ref struct bir yöntemi içeren bir Dispose() nesnesidir. Oluşturulan using deyim, deyiminin gövdesinde bir özel durum oluşturulsa bile kapsamın lock serbest bırakılmasını sağlar.
Aksi takdirde, deyimi tam olarak şunun lock eşdeğeridir:
object __lockObj = x;
bool __lockWasTaken = false;
try
{
System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken);
// Your code...
}
finally
{
if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj);
}
Kod bir try-finally deyimi kullandığından, bir deyiminin gövdesinde lock bir özel durum oluştursa bile kilit serbest bırakılır.
deyimininawait gövdesinde lock ifadeyi kullanamazsınız.
Yönergeler
.NET 9 ve C# 13'den başlayarak, en iyi performans için türün System.Threading.Lock ayrılmış bir nesne örneğini kilitleyin. Derleyici ayrıca bilinen Lock bir nesneyi başka bir türe yayınlar ve kilitlerseniz bir uyarı da yayınlar. Eski bir .NET ve C# sürümü kullanıyorsanız, başka bir amaç için kullanılmayan ayrılmış bir nesne örneğine kilitleyin. Kilitlenme veya kilit çekişmesiyle sonuçlanabileceği için farklı paylaşılan kaynaklar için aynı kilit nesnesi örneğini kullanmaktan kaçının. Özellikle, aşağıdaki örnekleri kilit nesneleri olarak kullanmaktan kaçının:
-
this, arayanlar da kilitleyebileceğindenthis. - Type örnekleri, typeof işleci veya yansıma tarafından elde edilebileceğinden.
- dize değişmez değerleri de dahil olmak üzere dize örnekleri , bunlar interned olabilir.
Kilit çekişmesini azaltmak için bir kilidi mümkün olduğunca kısa süre tutun.
Örnek
Aşağıdaki örnek, ayrılmış Account bir balance örneği kilitleyerek özel balanceLock alanına erişimi eşitleyen bir sınıfı tanımlar. Kilitleme için aynı örneği kullanmak, iki farklı iş parçacığının balance veya Debit yöntemlerini aynı anda çağırarak alanı güncelleştirememesini Credit sağlar. Örnek, C# 13 ve yeni Lock nesneyi kullanır. C# dosyasının eski bir sürümünü veya daha eski bir .NET kitaplığını kullanıyorsanız, örneğini kilitleyin object.
using System;
using System.Threading.Tasks;
public class Account
{
// Use `object` in versions earlier than C# 13
private readonly System.Threading.Lock _balanceLock = new();
private decimal _balance;
public Account(decimal initialBalance) => _balance = initialBalance;
public decimal Debit(decimal amount)
{
if (amount < 0)
{
throw new ArgumentOutOfRangeException(nameof(amount), "The debit amount cannot be negative.");
}
decimal appliedAmount = 0;
lock (_balanceLock)
{
if (_balance >= amount)
{
_balance -= amount;
appliedAmount = amount;
}
}
return appliedAmount;
}
public void Credit(decimal amount)
{
if (amount < 0)
{
throw new ArgumentOutOfRangeException(nameof(amount), "The credit amount cannot be negative.");
}
lock (_balanceLock)
{
_balance += amount;
}
}
public decimal GetBalance()
{
lock (_balanceLock)
{
return _balance;
}
}
}
class AccountTest
{
static async Task Main()
{
var account = new Account(1000);
var tasks = new Task[100];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = Task.Run(() => Update(account));
}
await Task.WhenAll(tasks);
Console.WriteLine($"Account's balance is {account.GetBalance()}");
// Output:
// Account's balance is 2000
}
static void Update(Account account)
{
decimal[] amounts = [0, 2, -3, 6, -2, -1, 8, -5, 11, -6];
foreach (var amount in amounts)
{
if (amount >= 0)
{
account.Credit(amount);
}
else
{
account.Debit(Math.Abs(amount));
}
}
}
}
C# dil belirtimi
Daha fazla bilgi için C# dil belirtimininkilit deyimi bölümüne bakın.