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

时间:2010-05-05 18:19:18

标签: 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;
    }

4 个答案:

答案 0 :(得分:10)

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

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

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

另见CA2002

答案 1 :(得分:6)

请注意,即使您在这里尝试做的事情是可能的(例如,如果DateTime是参考类型,因此您可以锁定),那么因为您正在设置它是不合法的NextCleanup lock块中的新值。

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

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

答案 2 :(得分:1)

看起来你要做的是定期运行清理程序。如果是这种情况,您可以使用System.Threading.Timer,它专门用于运行定期任务。

答案 3 :(得分:0)

不属于System.Object类型,但是有理由不使用对象吗?