C# · 12月 31, 2021

c# – 将lock()语句阻止proccess / appdomain中的所有线程?

也许这个问题听起来很愚蠢,但我不明白“关于线程和锁定的东西,我想得到一个确认( here’s why I ask).

所以,如果我有10个服务器和10个请求在同一时间来到每个服务器,这是整个农场的100请求.没有锁定,那100请求到数据库.

如果我做这样的事情:

private static readonly object myLockHolder = new object();if (Cache[key] == null){ lock(myLockHolder) { if (Cache[key] == null) { Cache[key] = LengthyDatabaseCall(); } }}

我会做多少数据库请求? 10? 100?或者我有线程?

解决方法 你有一个对象层次结构:

>你有服务器(10)
>每个服务器上都有进程(大概只有1个 – 你的服务/应用程序池)
>在每个进程中,你有线程(可能有很多)

您的代码只会禁止同一个进程中的线程在同一个服务器上同时修改Cache对象.您可以跨进程创建锁,甚至跨服务器进行锁定,但是当您向上移动层次结构时,成本会增加很多.

使用lock语句实际上并不锁定任何线程.但是,如果一个线程正在执行锁中的代码(即在锁定语句后面的代码块中),那么想要执行锁定并执行相同代码的任何其他线程都必须等到持有锁的第一个线程离开代码块并释放锁.

C#锁定语句使用一个轻量级锁定机制的Windows critical section.如果要跨进程锁定,可以使用mutex.要跨服务器进行锁定,您可以使用数据库或共享文件.

正如dkackman所指出的那样,.NET有一个AppDomain的概念,它是一种轻量级的过程.每个进程可以有多个AppDomains. C#锁定语句仅在单个AppDomain中锁定资源,并且层次结构的正确描述将包括进程下方的AppDomain以及线程上方.然而,很多时候,您只能在一个进程中单独使用AppDomain,使得该区别有些无关紧要.