2013-01-17 53 views
3

我正在使用Threading.Timer在我的应用程序中运行消息泵。替代Monitor.TryEnter在NET 3.5

有时候需要的工作需要的时间比计时器间隔的时间间隔长,我需要将代码“跳过”。

我写了一个小的测试程序进行测试,并保持运行到我锁定一个SynchronizationLockException:

static void Main(string[] args) 
{Program t = new Program(); 
    System.Threading.Timer myTimer = new Timer(t.Tick,null,1000,1000); 

    Thread.Sleep(10000); 
    myTimer.Change(0,0); 
    Console.WriteLine("Waiting on lock in main thread..."); 
    Monitor.Enter(t.myLock); 
    Console.WriteLine("Done"); 
    Monitor.Exit(t.myLock); 

} 

public readonly Object myLock = new Object(); 
public void Tick(object state) 
{ 
    Console.WriteLine("Acquiring lock! From thread " + Thread.CurrentThread.ManagedThreadId); 
    Monitor.TryEnter(myLock); 
    try 
    { 
    Thread.Sleep(6000); 
    Console.WriteLine("Inside workload!From thread " + Thread.CurrentThread.ManagedThreadId); 
    } 
    finally 
    { 
    Console.WriteLine("Releasing lock!From thread " + Thread.CurrentThread.ManagedThreadId); 
    Monitor.Exit(myLock); 
    } 

} 

我现在不能回忆链接,但我已经找到了建议的解决方法我最初的要求通过在回调函数的开始和结束时禁用和启用计时器,但由于文档指出在计时器停止后,它仍然可以调用 ,因为它可能已经在.NET ThreadPool上进行了调度。

我在这里丢失了一些明显的东西,还是显示器不能正常工作? 我在.NET 3.5,所以

Monitor.TryEnter(myLock,hasLock)

家饭店没有一个选项。

+0

我前一阵子实现与此类似,您在正确的轨道与'Monitor.TryEnter' /'Monitor.Lock'上,如果你想*跳过*处理。看到我的[问题](http://stackoverflow.com/questions/1698393/using-lock-with-threading-timer)。 – James

回答

8

Monitor.TryEnter()方法返回一个布尔值,你忽略它。当您尝试退出您从未真正输入的锁时,您看到的错误会发生。

要快速解决您的当前代码:

//Monitor.TryEnter(myLock); 
if (! Monitor.TryEnter(myLock)) return; 
+1

+1或同时!如果您需要等待,请暂停。我认为在很多情况下,在短时间内没有获得锁是应用程序例外。 – kenny

+0

@HenkHolterman谢谢,这对我来说是一个相当糟糕的疏忽--.-。 – Vort3x