使用除锁定对象以外的其他锁定线程
使用锁定时,锁定的对象必须是对象。例如,这是合法的使用除锁定对象以外的其他锁定线程
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;
}
请注意,即使您在此尝试做的事情是可能的(例如,如果DateTime
是引用类型,因此您可以锁定),但这并不合法,因为您将NextCleanup
设置为lock
区块内的新值。
您无法在锁定该对象的代码块中设置对新对象的引用。
这就是为什么建议有一个专用的“锁”对象用于所有需要同步以用于相关目的的代码。
您可以锁定任何引用类型。
由于DateTime不是引用类型,因此无法锁定它。
如果您尝试,每次拨打电话Monitor.Enter
都会收到一个不同的盒装DateTime
值,并且锁定将无效。
你想做什么?
就运行时而言,无论您锁定哪个对象都无关紧要。 (锁定一个对象不会奇迹般地阻止其他线程使用该对象,除非它们明确地锁定在同一个对象上)
当你锁定一个对象时,你应该选择一个对象,所有必要的代码段将锁定。请参阅CA2002。
应该注意的是,所有的引用类型都是对象,所以不需要投射。另外,确保你使用的变量锁总是指向同一个对象。 – 2010-05-05 18:23:24
伟大的答案 - 我将不得不记住这一点,以备将来参考! – Dave 2010-05-05 18:26:19
我想要做的只是防止另一个线程检查,看看它是否可以更新之前已经过去了一小时。 – 2010-05-05 18:29:34
它不有是System.Object
类型的,但有一个理由不使用一个对象?
阅读我的更新。我的意思是'System.Object'。 – 2010-05-05 18:23:28
我想约翰在说什么,它不需要像输入的OP那样转换为System.Object。或者他可能意味着你不必创建一个System.Object成员,然后使用* that *作为锁。我只是这样说,因为作为一个新手,我以前只是为了锁定而创建了一个System.Object,因为所有东西都是从System.Object派生的,所以我几乎可以使用任何东西。 – Dave 2010-05-05 18:25:20
@SLaks:它必须是一个参考类型。我认为约翰意味着它不一定是最小的'System.Object',但可以是从它派生的任何引用类型。 – 2010-05-05 18:25:33
看起来你正在试图做的是定期运行一个清理程序。如果是这种情况,可以使用System.Threading.Timer,它专门用于运行定期任务。
这是第一个很好的解释,为什么你应该使用一个单独的对象进行锁定,而不是你计划使用的对象。 – 2010-05-05 18:33:08