بررسی شیء جدید Lock در C# 13 و داتنت 9
نویسنده: وحید نصیری
تاریخ: ۱۴۰۳/۰۹/۰۱ ۲۱:۵۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
private readonly object _syncRoot = new();
public void DoSomething()
{
lock (_syncRoot)
{
// Do something
}
}using System.Runtime.CompilerServices;
using System.Threading;
namespace CS13Tests
{
public class NewLockObjectTests
{
[Nullable(1)]
private readonly object _syncRoot;
public void DoSomething()
{
object syncRoot = this._syncRoot;
bool lockTaken = false;
try
{
Monitor.Enter(syncRoot, ref lockTaken);
}
finally
{
if (lockTaken)
Monitor.Exit(syncRoot);
}
}
public NewLockObjectTests()
{
this._syncRoot = new object();
base..ctor();
}
}
}private readonly Lock _syncRoot = new();
public void DoSomething()
{
lock (_syncRoot)
{
// Do something
}
}using System.Runtime.CompilerServices;
using System.Threading;
namespace CS13Tests
{
public class NewLockObjectTests
{
[Nullable(1)]
private readonly Lock _syncRoot;
public void DoSomething()
{
Lock.Scope scope = this._syncRoot.EnterScope();
try
{
}
finally
{
scope.Dispose();
}
}
public NewLockObjectTests()
{
this._syncRoot = new Lock();
base..ctor();
}
}
}using var scope = _syncRoot.EnterScope();
using (_syncRoot.EnterScope())
{
// ...
}public class NewLockObjectTests
{
private readonly Lock _lock = new();
private void Do()
{
_lock.Enter();
try
{
// ....
}
finally
{
if (_lock.IsHeldByCurrentThread)
{
_lock.Exit();
}
}
}using BenchmarkDotNet.Attributes;
namespace CS13Tests;
public class NewLockObjectBenchmarks
{
private const decimal Amount = 100m;
private const int TaskCount = 1000;
private const int OperationsPerTask = 1000;
[Benchmark]
public decimal TestTraditionalLock()
{
var account = new TraditionalLockAccount();
Parallel.For(fromInclusive: 0, TaskCount, _ =>
{
for (var i = 0; i < OperationsPerTask; i++)
{
account.Deposit(Amount);
}
});
return account.GetBalance();
}
[Benchmark]
public decimal TestNewLock()
{
var account = new NewLockAccount();
Parallel.For(fromInclusive: 0, TaskCount, _ =>
{
for (var i = 0; i < OperationsPerTask; i++)
{
account.Deposit(Amount);
}
});
return account.GetBalance();
}
public class TraditionalLockAccount
{
private readonly object _syncRoot = new();
private decimal _balance;
public void Deposit(decimal amount)
{
lock (_syncRoot)
{
_balance += amount;
}
}
public decimal GetBalance() => _balance;
}
public class NewLockAccount
{
private readonly Lock _syncRoot = new();
private decimal _balance;
public void Deposit(decimal amount)
{
using var scope = _syncRoot.EnterScope();
_balance += amount;
}
public decimal GetBalance() => _balance;
}
}
/*
| Method | Mean | Error | StdDev |
|-------------------- |---------:|--------:|---------:|
| TestTraditionalLock | 137.3 ms | 3.82 ms | 11.28 ms |
| TestNewLock | 115.8 ms | 1.50 ms | 1.41 ms |
*/Error CS1996 : Cannot await in the body of a lock statement