Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我应该在多线程范例中锁定数据表吗?_C#_Multithreading_Caching - Fatal编程技术网

C# 我应该在多线程范例中锁定数据表吗?

C# 我应该在多线程范例中锁定数据表吗?,c#,multithreading,caching,C#,Multithreading,Caching,在windows服务(C#.Net平台)项目中,我需要一个建议。 在这个项目中,我有一个名为Cache的类,在这个类中我保存了一些我经常需要的数据。有一个线程每30分钟更新一次缓存。其中有多个线程使用缓存数据。 在cache类中,有getter和setter函数,分别由用户线程和cache更新线程使用。没有人直接使用像表这样的数据对象,因为它们是私有成员。 从上面的上下文来看,您认为我应该在缓存类中使用锁定功能吗?写入共享内存位置(如缓存)时不使用锁定的效果实际上取决于应用程序。如果代码用于银行

在windows服务(C#.Net平台)项目中,我需要一个建议。
在这个项目中,我有一个名为Cache的类,在这个类中我保存了一些我经常需要的数据。有一个线程每30分钟更新一次缓存。其中有多个线程使用缓存数据。
在cache类中,有getter和setter函数,分别由用户线程和cache更新线程使用。没有人直接使用像表这样的数据对象,因为它们是私有成员。

从上面的上下文来看,您认为我应该在缓存类中使用锁定功能吗?

写入共享内存位置(如缓存)时不使用锁定的效果实际上取决于应用程序。如果代码用于银行软件,结果可能是灾难性的


根据经验,当多个线程访问同一个位置时,即使只有一个线程写入而所有其他线程读取,也应该使用锁(用于写入操作)。可能发生的情况是,一个线程将开始读取数据,被更新程序线程刷出;因此,它最终可能会混合使用新旧数据。如果这真的是一种影响,则取决于应用程序及其合理性。

关键点:如果不锁定读取,则您的读取可能看不到更改。锁将强制读取代码从主内存获取值,而不是从缓存或寄存器中提取数据。为了避免实际锁定,可以使用Thread.MemoryBarrier(),它将执行相同的工作,而不会产生实际锁定任何内容的开销

次要问题:使用锁可以防止读取得到一半的旧数据和一半的新数据。如果您正在阅读多个字段,我建议您使用它。如果您真的很聪明,那么可以将所有数据保存在一个不可变对象中,并将该对象返回给调用getter的任何人,从而避免使用锁。(当新数据进入时,您创建一个新的不可变对象,然后一次性用新对象替换旧对象。对实际写入使用锁,或者,如果您仍然感觉非常聪明,则使引用该对象的字段不稳定。)


另外:调用getter时,请记住它正在许多其他线程上运行。有一种倾向认为,一旦某个东西运行了缓存类的代码,它就都在同一个线程上,而事实并非如此。

缓存是单线程的吗?是否有比更新程序线程优先级更高的线程?是的,缓存是单线程的。Sidenote-有一些用于缓存的库,它们的优先级完全相同-例如Microsoft Enterprise Library。为什么要重新发明轮子?@OndrejSvejdar:有时我们需要太多的定制,这最终导致以不同的模式重新发明轮子。你建议我是在setter中更新缓存对象时锁定它,还是在getter中读取它?我认为锁定二传会更好@纳迪姆贾马利:都是!我的回答集中在阅读问题上;我只是假设写锁是必要的。这里可能有避免锁定的方法,但您必须做其他事情(如不可变对象和易变字段),并且您必须知道自己在做什么。我想说的关键点是,如果不锁定读取,特别是在写入几秒钟内发生读取,可能根本看不到更改。他们可能只看到几次更新后的更改,甚至根本看不到更新。