`

C# 中的 lock的陷阱

    博客分类:
  • C#
阅读更多
旧事重提了,或许很多人会奇怪,为什么 C# 不允许lock一个struct ? 例如:

public void ProcessTask(int taskid){
    lock(taskid){  .....   }
}

编译说lock只能使用引用类型。有些人聪明(我想我以前也有这样的"聪明"。。),这样做: lock((object)taskid){...}

但是,实际的经验告诉我,这样行不通,lock需要的是引用,严格来说是需要对象的实例。

即使对象在意义上是相同的,但是如果不是ReferenceEquals的话,那么将作为两个实例来对待,那么C# lock 的就不是同一个东西。也就是说,当你以为这个 lock 生效的话,它其实在做无用工。

在上面的例子,由于lock((object)taskid)每执行一次,taskid都进行一次装箱,而装箱后的对象不是同一个实例(都是完完全全的新的实例),所以 lock((object)taskid){...} 是白做了。

当然,lock((object)123){} 这样的做法也是一样有问题的。

但是这种就好点:lock(“helloworld“){} 。为什么只是“好点”,而不是“没有问题”了呢。原因在于DotNet分配字符串的机制。DotNet为每个Assembly里的字符串都分配固定的空间。所以每次引用“helloworld“的时候,是同一个实例。但是这个字符串不会在其他Assembly中得到共用。如果几个Assembly都是这样写的,那么它们各自有她们自己的“helloworld“

比较好的做法:

lock(this)...
lock(typeof(ThisType))
lock(GetType())//除非你明白这是干什么,否则不要乱来。
lock(SomeType.StaticSyncObject)
lock(someinst.SyncObject)
其他的一些不好的做法

lock(“task:“+id)
lock(filename)
当然,具体lock什么东西,是设计上的协议和规范。不过要注意的是,使用lock必须明确对象是不是想象中的同一实例。

如果需要针对一个变化的值,从它的意义上的Equals方面进行 lock ,那怎么办?
这个可以参考  http://www.lostinet.com/files/ 下的 HashCodeLock (里面很多细节可以优化)

转自“迷失网络”的Blog:http://blog.joycode.com/lostinet/archive/2004/05/21/22123.aspx
分享到:
评论

相关推荐

    c#多线程.rar

    多线程是C#中的一个重要概念,它允许程序同时执行多个任务,从而提高应用程序的效率和响应性。本资源“c#多线程.rar”可能包含一系列关于如何在C#中实现和管理多线程的实例代码。 在C#中,`System.Threading`命名...

    C#进程和线程资料集锦

    - **c#多线程编程笔记.rar**:可能是一位开发者的经验总结,包含了实践中的技巧和陷阱,对于理解和应用多线程编程非常有价值。 掌握这些知识后,无论是初学者还是中高级开发者,都能在C#环境下高效地编写多线程应用...

    C#线程参考手册.rar

    最后,书中还会讨论一些高级话题,如线程间通信(如使用Channel或EventWaitHandle)、线程中断(Abort方法的使用和陷阱)以及如何利用Task Parallel Library (TPL) 和 PLINQ 进行并行计算。 总之,《C#线程参考手册...

    C#多线程开发技术总结

    在C#编程中,多线程是一项至关重要的技术,它允许程序同时执行多个任务,从而提高了应用程序的效率和响应性。以下是对C#多线程开发技术的详细总结: 一、线程基础知识 1. 线程的概念:线程是操作系统分配处理器时间...

    C#多线程学习入门圣典(修改版)

    ### C#多线程学习入门圣典(修改版) #### C#多线程学习(一) 多线程的相关概念 - **什么是进程?** - 当一个程序开始运行时,它就是一个进程。...然而,合理地使用这些工具并避免常见的陷阱同样重要。

    当析构函数遇到多线程── C++ 中线程安全的对象回调 PDF

    例如,Java中有`WeakReference`,C#中有`WeakReference<T>`等。 #### 14. 心得与总结 通过使用`boost::shared_ptr`和`boost::weak_ptr`,我们可以有效地解决C++多线程编程中关于对象生命期管理的问题。这些智能...

    线程安全调用

    - 在C#中使用`lock`关键字,在VB.NET中使用`SyncLock`。 - 注意使用`lock(typeof(X))`或`SyncLock(GetType(X))`来锁住类型对象时,同一类型下的所有实例将共享相同的锁,可能不是预期的行为。 - 使用`lock(this)`...

    .Net中常见问题及解决方法归类

    本文将对.NET中的一些常见问题进行总结,并提出相应的解决方案,帮助开发人员提高工作效率,避免常见的陷阱。 #### 二、基础知识回顾 在深入讨论问题之前,我们先简要回顾一下.NET框架的基础概念: - **.NET ...

    WPF 已知问题 清空 CollectionView 的 SortDescriptions 可能抛出空异常.rar

    然而,如同任何复杂的系统一样,WPF也存在一些已知的问题和陷阱,开发者在日常工作中需要特别注意。本篇文档将深入探讨一个特定的问题:在尝试清空CollectionView的SortDescriptions时可能会遇到的空引用异常。 ###...

    net gotachas

    .NET Gotchas是一个广泛使用的术语,指的是在开发.NET应用程序时可能会遇到的陷阱或意外情况。...通过阅读官方文档、参加培训课程、参与社区讨论,开发者可以更好地理解和规避.NET Framework中的潜在陷阱。

Global site tag (gtag.js) - Google Analytics