前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >C# 13 lock object

C# 13 lock object

作者头像
JusterZhu
发布2025-01-23 20:38:52
发布2025-01-23 20:38:52
5200
代码可运行
举报
文章被收录于专栏:JusterZhuJusterZhu
运行总次数:0
代码可运行

C# 13 lock object

Intro

.NET 9 引入了一个新的 Lock 类型 System.Threading.Lock .NET 9 Preview 1 中的 Lock 类型

我们可以使用这一类型代替 lock 的对象来改进锁的性能

Sample

我们来做一个简单的 benchmark

代码语言:javascript
代码运行次数:0
复制
[SimpleJob]
[MemoryDiagnoser]
public class LockObjectBenchmark
{
    private readonly object _lock0 = new();
    private readonly Lock _lock1 = new();

    [Benchmark(Baseline = true)]
    public int NewLockObject()
    {
        var i = 0;
        Parallel.For(1, 1000, _ =>
        {
            lock (_lock1)
            {
                Interlocked.Increment(ref i);
            }
        });
        return i;
    }

    [Benchmark]
    public int TraditionalLock()
    {
        var i = 0;
        Parallel.For(1, 1000, _ =>
        {
            lock (_lock0)
            {
                Interlocked.Increment(ref i);
            }
        });
        return i;
    }
}

benchmark-result

从结果可以看得出来新的锁的类型性能更好,分配更少

默认地 lock 会使用 Monitor 是实现锁,我们使用 lock 默认就是 Monitor 的语法糖,难以扩展

lock-implemention

.NET 9 引入的 System.Threading.Lock 类型实现一定程度上的自定义,只是目前是针对这个 type 做了特殊处理,未来可能会制定一个规则只要满足规则都可以作为锁的类型,类似于 GetEnumerable/GetAwaiter 那样

我们再来看下使用 System.Threading.Lock 类型之后还是不是 Monitor

原始测试代码

代码语言:javascript
代码运行次数:0
复制
var i = 0;
var locker = new Lock();
Parallel.For(1, 100, _ =>
{
    lock (locker)
    {
        i++;
    }
});
Console.WriteLine(i);

反编译之后的结果:

System.Threading.Lock

可以看到,现在的代码里已经没有了 Monitor,lock 变成了 usings (locker.EnterScope())

再细看实现代码会发现实现是一个自旋,具体可以自己查看源码

https://github.com/dotnet/runtime/blob/v9.0.0-rc.1.24431.7/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs

More

如果想要使用 System.Threading.Lock 但又还有低版本的框架不支持 System.Threading.Lock 该怎么办呢,github 上有个老哥搞了个 Backport.System.Threading.Lock library 兼容低版本的,但是测试下来低版本没有性能提升反而有性能损耗,看了下实现和源码的实现并不相同,他是基于 Monitor 封装了一下

我们可以通过 global using alias 来简化例如:global using Lock = System.Object; 或者在项目文件或者 Directory.Build.props 中配置 implicit usings:

代码语言:javascript
代码运行次数:0
复制
<Using Include="System.Object" Alias="Lock" Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net9.0'))" />

References

  • https://github.com/dotnet/csharplang/blob/main/proposals/csharp-13.0/lock-object.md
  • https://github.com/dotnet/runtime/issues/34812
  • https://github.com/dotnet/csharplang/issues/7104
  • https://github.com/dotnet/runtime/blob/v9.0.0-rc.1.24431.7/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs
  • https://github.com/WeihanLi/WeihanLi.Common/pull/212
  • .NET 9 Preview 1 中的 Lock 类型
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-09-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JusterZhu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C# 13 lock object
    • Intro
    • Sample
    • More
    • References
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档