永发信息网

关于类似Application.Lock的问题,我想实现对多个连接对同一资源的同步

答案:2  悬赏:0  手机版
解决时间 2021-08-18 14:17
  • 提问者网友:谁的错
  • 2021-08-17 18:32
我想实现多个连接,共同提供数据和获取数据.(这些数据是相同的,存储在同一个位置的)
因为存储的数据量不太大.而连接又会很多.提供/获取数据的操作又会很频繁,所以用数据库存储开销很大
因此我想直接把数据保存在内存中.而在asp.net中可以提供多个连接访问相同数据就只有Application了.对了.static变量是不是也可以?
因为多个连接要操作和获取同一数据.所以可能存在情况:一个连接正在修改数据,而另一个连接要获取前一连接要修改的数据.
如果单单这样的话,直接用lock来解决问题.就是不知道lock是锁住整个Application
还是Application.Items中的一项呢,我没试过,但我认为是锁住全部.所以希望有人能有过成功测试的回答
如果是锁住整个app(Application,下面都这样简写)的话,那么无非会浪费其他连接修改app.Items里其他不相关数据的时间.

如果对上面我的描述不太理解的话,那么我就要举个事例来说明了:
假设有3个同时访问的连接:1,2,3
app里有Items:{"a"="数据..","b"="数据.."}

连接1是要修改app里的a数据,而连接2慢了一点点,是要获取a数据,这个时候因为连接1要修改a数据,那么就需要lock app,所以连接2需要等待(是不是这样?),这个时候连接3是与连接2同时的,它要访问b数据,这个时候你说他是等待还是可以直接获取呢?(还没 UnLock)

如果不能简单的解决上面的问题,那么我提供我的一个思路(不完善,实在找不到资料了):
利用反射或动态编译等方法,添加一个Application的静态变量(或者其他一直存在的类的静态变量,反正就是这个意思.说的不清楚,因为我不知道能不能实现,望见谅)
接上面的例子,因为如a,b这些数据,个数是不确定的,但是他的个数是在程序一开始执行就确定了的,所以我想在程序一开始,就动态的添加这些静态变量,然后把这些变量的引用保存进app,以后直接用app[key]来取或修改那些数据

问题描述完毕.如果有需要更详细的问题,请在跟帖说明,希望会的朋友能给出相关的代码,而不是简单的文字说明,谢谢!
最佳答案
  • 五星知识达人网友:掌灯师
  • 2021-08-17 19:04

解决数据库瓶颈的根本在于重复访问,在ASP.NET里面是通过cache来解决的。


不要在真实项目中使用静态变量存储数据,除非是单机版程序或XML对象。


对于并发访问冲突,其实更重要的是你的设计,资源访问权限和资源修改权限,分布到每一个实例对象上,


自然不会有冲突产生。


不然lock来lock去,你会发现你自己的思维都被这个lock给锁死了;最终,lock成为了性能的瓶颈。


有空可以看一下设计模式,作为ASP.NET的面向对象入门,


很多程序员在工作了3,5年之后每次碰到问题还是总是去寄托希望与代码的解决方案身上。


事实上,差距不在你的CODE或者是实现上,而是你的设计和抽象上就已经失败了。

全部回答
  • 1楼网友:蕴藏春秋
  • 2021-08-17 20:04

lock 既不会锁定 Application 也不会锁定 Application,它锁定的是代码段。

比如 lock(obj){....} 这段代码不是指在把obj加锁的时候不允许其它地方访问,而是说阻止多个线程进入这同一段代码内部……它们在要执行这段代码的时候,必须能先lock()这个obj才行,否则就会在这里等待。所以当多个地方存在 lock(obj) 的时候,会构成互斥,它们必须要等到能执行 lock 的时候,才能继续执行,否则就必须等待。但是,当你使用 lock(obj) 锁定这个对象的时候,在没有使用 lock(obj) 再请求锁定的代码里,obj这个对象仍然是可以被继续访问或任意修改的。所以,如果你在修改的时候用 lock() 锁定了对象,其它读取、修改的时候,只要没有再去用lock请求锁,代码都是可以继续执行的,不会有任何影响。从这个方面来解释,你担心的连接1在修改,连接2,3等读取都是不会需要等待的,除非读取的时候它们都请求去lock掉Application。

所以,从这方面看,你这里使用lock似乎没有必要,除非变量的改动相当频繁可能会发生多个线程同时去修改,那可以考虑用lock。

我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯