C#locking语句,什么对象locking?

我有3个问题需要帮助。

  1. 什么是正确的对象/引用作为lock语句parameter passing? 我见过很多示例代码,并且我注意到,只要访问修饰符static是非公开的,那么传入的对象/引用可能与程序中的当前类或任何其他类无关。 例如:

     private Object anyObj = new Object(); lock(anyObj){.....} private static readonly object Locker = new object(); lock(Locker){.....} 

    这对我来说没有意义。

  2. 我在MSDN中find了一个关于使用lock语句的multithreading的示例代码。 在示例中,有两个try / catch块,其中包含Monitor.Wait() 。 如果我正确理解逻辑, readerFlag将禁止该程序永远进入try / catch块。
    代码是从这里的例子2:
    http://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx

  3. 只要Windows窗体处于活动状态,如何运行在后台运行的线程?

任何人都可以帮我吗? 我已经在网上search了很多个小时,而我却无法得到我想要的答案。

你如何和什么locking取决于你在做什么。

假设您正在使用某种设备 – 比如咖啡机。 你可能有一个如下所示的类:

 public CoffeeMaker { private IntPtr _coffeeHandle; private Object _lock = new Object(); } 

在这种情况下,您正在保护对_coffeeHandle的访问 – 一个指向真实物理设备的指针/句柄,所以这很简单:

 public int AvailableCups { get { lock (_lock) { return GetAvailableCups(_coffeeHandle); // P/Invoked } } } public void Dispense(int nCups) { lock (_lock) { int nAvail = GetAvailableCups(_coffeeHandle); if (nAvail < nCups) throw new CoffeeException("not enough coffee."); Dispense(_coffeeHandle, nCups); // P/Invoked } } 

所以,如果我正在运行一个multithreading的应用程序,我(可能)不想读取我分配时可用的杯的数量(也许这是一个硬件错误)。 通过保护对手柄的访问,我可以确保。 而且,当我已经分配的时候,我不能被要求分配 – 这将是不好的,所以这也是保护。 最后,除非我有足够的咖啡,否则我不会分配,你注意到我没有使用我的公共财产来检查 – 这样确保有足够的咖啡和分配的行动被捆绑在一起。 这个魔法字是primefaces的 – 它们不能被分割而不会造成问题。

如果您有一个且只有一个需要保护的资源实例,则使用静态对象作为锁。 想想,“我有单身吗?” 这将是您何时需要静态locking的指导原则。 例如,假设CoffeeMaker有一个私有的构造函数。 相反,你有一个构造咖啡机的工厂方法:

 static Object _factLock = new Object(); private CoffeeMaker(IntPtr handle) { _coffeeHandle = handle; } public static CoffeeMaker GetCoffeeMaker() { lock (_factLock) { IntPtr _handle = GetCoffeeMakerHandle(); // P/Invoked if (_handle == IntPtr.Zero) return null; return new CoffeeMaker(_handle); } } 

现在在这种情况下,感觉就像CoffeeMaker应该实现IDisposable,以便处理得到处理,因为如果你不释放它,那么有人可能不会得到他们的咖啡。

但也有一些问题 – 如果没有足够的咖啡,我们应该做更多 – 这需要很长时间。 喝点咖啡需要很长时间,这就是为什么我们要小心保护我们的资源。 现在,你正在想,所有这些咖啡机的东西都应该在自己的线程中,当咖啡完成后,应该有一个事件被解雇,然后开始变得复杂,并且你明白知道的重要性你locking什么东西,什么时候让你不要因为问你有多less杯子而堵塞咖啡。

如果“死锁”,“primefaces”,“显示器”,“等待”和“脉冲”这些词听起来都与你有关,你应该考虑阅读一般的多处理/multithreading,看看你是否能解决公平的理发店问题还是餐饮哲学家的问题 ,都是资源争夺的典型例子。

1)你的代码不完整。 你总是locking某个(共享)资源。 anyObject应该在生命周期中与该共享对象具有接近的anyObject

例如:

a)简单但最直接的模式:

 List<MyClass> sharedList = ...; ... lock (sharedList) { sharedList.Add(item); } 

这种模式有一个缺点:如果其他代码也由于其他原因locking在sharedList呢? 通常不是一个实际的问题,但是推荐的模式是(b):

 List<MyClass> sharedList = ...; private object listLock = new object(); ... lock (listLock) { sharedList.Add(item); } 

或者,当共享对象是静态的(c)时:

 static List<MyClass> sharedList = ...; private static object listLock = new object(); ... lock (listLock) { sharedList.Add(item); } 

2)线程交替设置readerFlag为真或假,所以try / catch块将被input。 通过Monitor.Pulse()和.Wait()完成同步。 请注意,Wait()将产生持续时间为s的锁,而不存在死锁。

1:你使用的对象是/正在定义的 – 你试图执行的锁粒度。 如果is是“任何调用当前实例的东西”,则private readonly object syncLock = new object()将是合理的。 如果是“任何代码,不pipe实例”(特别是静态),那么private readonly static object syncLock = new object() 。 有时候,有一个明显的“事情”,你试图保护,这也将服务:列表,队列等。主要的错误决定是: thistypeof(...) ,任何string ,任何值types,你拳击每个lock ,以及任何你泄露的实例外。

2: Monitor.Wait从当前线程释放锁,等待一个“脉冲”或超时,在这一点醒来,并join队列重新获得locking它(注意“s”有重新-entrancy)。 这意味着两个线程可以使用一个Monitor通过脉冲和等待在它们之间发出信号

3:不相关; 但基本上是“定期检查一下旗帜,当脉冲”

根据MSDN文档 :

提供给lock关键字的参数用于定义锁的范围。 严格来说,提供的对象仅用于唯一标识多个线程之间共享的资源,因此它可以是任意的类实例。 然而,在实践中,这个对象通常代表线程同步所必需的资源。

在我的情况下,我已经通过了我需要改变的确切的静态对象。

我希望这有帮助。