使用对象以外的东西锁定线程

Sco*_*ain 3 c# locking

当使用锁时,你锁定的东西必须是一个对象.例如,这是合法的

    static DateTime NextCleanup = DateTime.Now;
    const TimeSpan CleanupInterval = new TimeSpan(1, 0, 0);
    private static void DoCleanup()
    {
        lock ((object)NextCleanup)
        {
            if (NextCleanup < DateTime.Now)
            {
                NextCleanup = DateTime.Now.Add(CleanupInterval);
                System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(cleanupThread));
            }
        }
        return;
    }
Run Code Online (Sandbox Code Playgroud)

SLa*_*aks 10

您可以锁定任何引用类型.

由于DateTime不是引用类型,因此无法锁定它.
如果你尝试,每次调用Monitor.Enter将收到一个不同的盒装DateTime值,锁定将是无效的.

你想做什么?
就运行时而言,根本锁定的对象并不重要.(锁定一个对象不会神奇地阻止其他线程使用该对象,除非它们明确锁定同一个对象)
当你锁定一个对象时,你应该选择一个所有必要的代码片段都将锁定的对象.

另见CA2002.

  • 应该注意的是,所有引用类型都是对象,因此不需要进行转换.此外,请确保您使用锁定的变量始终引用同一个对象. (2认同)

Dan*_*Tao 6

请注意,即使您尝试在此处执行的操作是可能的(即,如果它DateTime是引用类型,因此您可以锁定它),那么这将是不合法的,因为您在块中设置NextCleanup了新值lock.

您无法在已锁定该对象的代码块中设置对新对象的引用.

这就是为什么建议使用专用的"锁定"对象来为所有需要为相关目的进行同步的代码.