多线程同步的正确模式? (C#)

时间:2009-11-08 18:41:53

标签: c# synchronization multithreading

我有两个线程引用相同的变量 - UI线程和计时器线程。因此,我在两个线程的锁定语句中包装了对它的访问。定时器线程的访问具有优先级 - 如果它使用变量并且UI线程也想要访问,我希望UI线程的操作完成,但只有在定时器线程的操作完成之后。

但是,计时器线程可以委托回UI线程,因此UI线程需要可以自由处理。为了适应这种情况,我让UI线程启动第三个线程来处理它的操作,以便它(第三个线程)可以等待定时器操作完成并且UI线程可用。锁定发生在第三个线程中。

我应该使用哪种正确的模式进行这种同步?

5 个答案:

答案 0 :(得分:6)

一般建议是,关键部分发生的事情应该尽可能简单。特别是你应该避免嵌套锁。嵌套锁可能是死锁的来源。

当应用于你在'计时器'线程中所做的事情时,你可能应该将关键部分与处理区分开来。 IW在计时器线程中只检索公共变量中的数据,然后执行剩余的处理,包括与锁外的UI线程的交互。

添加第三个线程不会让你的生活更轻松

答案 1 :(得分:2)

经验法则是尽可能使用最轻的锁定最短时间。

这里有一篇很好的文章:http://www.moserware.com/2008/09/how-do-locks-lock.html

答案 2 :(得分:1)

遵循的一般规则是您最小化持有锁的时间,并且不调用您不拥有和控制的代码(例如事件,虚拟方法或UI线程) )拿着锁。

因此,在持有锁定时,计时器不应回调到UI。如果它需要对锁定下的数据进行事务性访问(读取,调用UI,写入),那么它应该设计为回滚和/或重试。

答案 3 :(得分:0)

像mfeingold所说,尽可能避免它。在你无法避免的地方,请注意以相同的顺序取两个线程中的锁!我的意思是,如果您有三个锁A,B和C,如果您有以下锁定模式

  • 线程1:A-> B-> C
  • 线程2:A-> C-> B

然后可能出现死锁......

嵌套锁通常会降低性能,因为必须锁定外部锁,即使在从另一个线程调用该方法的情况下有时也不需要确保正确的行为。

答案 4 :(得分:0)

你为什么要这样做?这听起来很复杂且容易出错。

什么是委托给UI线程的计时器线程?

情况可能是必要的,但我的反应是你可能需要退一步考虑你的设计是否会不必要地迫使你进入复杂的同步问题。