2013-01-17 85 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