2011-01-19 85 views
2

在廣泛閱讀了SO後,我瞭解到Thread.Sleepa bad idea。相反,普遍的共識是服務器端任務應該使用Timer,threadpool或者可以使用Join()我應該使用Timer,ThreadPool,AutoResetEvent還是使用模擬「加入」?

一個article提到處置定時器的困難。

另一個article提及使用waitOne

問題

什麼是推出一個長期運行的任務,將重複每隔30秒,1分鐘或5分鐘時要使用正確的方法?約束條件是,如果該任務的上一次運行比間隔(32秒或7分鐘)更長,那麼我希望該選項殺死前一個實例或不執行新實例。

一個潛在的疑難雜症的是,我打算使用爲使用模擬上這些線程要麼WindowsImpersionationContext,P /調用LogonUserEX,或DCOMShim根據需要。

我不知道採取什麼方法,爲什麼。

可能的答案1

這個例子似乎簡單明瞭,用最少的代碼混亂

// initially set to a "non-signaled" state, ie will block 
    // if inspected 
    private readonly AutoResetEvent _isStopping = new AutoResetEvent(false); 
    /// <summary> 
    /// from... 
    /// https://stackoverflow.com/questions/2822441/system-timers-timer-threading-timer-vs-thread-with-whileloop-thread-sleep-for-p/2822506#2822506 
    /// </summary> 
    public void SampleDelay1() 
    { 
     TimeSpan waitInterval = TimeSpan.FromMilliseconds(1000); 

     // will block for 'waitInterval', unless another thread, 
     // say a thread requesting termination, wakes you up. if 
     // no one signals you, WaitOne returns false, otherwise 
     // if someone signals WaitOne returns true 
     for (; !_isStopping.WaitOne(waitInterval);) 
     { 
      // do your thang! 
     } 
    } 

可能的答案2

這個例子提供了類似的功能,但使用匿名類型這在那些不符合其編碼標準的公司中可能是不允許的。

/// <summary> 
    /// Disposable Timer instance from 
    /// https://stackoverflow.com/questions/391621/compare-using-thread-sleep-and-timer-for-delayed-execution 
    /// </summary> 
    class TimerStackOverFlow 
    { 
    // Created by Roy Feintuch 2009 
     // Basically we wrap a timer object in order to send itself as a context in order 
     // to dispose it after the cb invocation finished. This solves the problem of timer 
     // being GCed because going out of context 
     public static void DoOneTime(ThreadStart cb, TimeSpan dueTime) 
     { 
      var td = new TimerDisposer(); 
      // Is the next object System.Timers, or System.Threading 
      var timer = new Timer(myTdToKill => 
      { 
       try 
       { 
        cb(); 
       } 
       catch (Exception ex) 
       { 
        Trace.WriteLine(string.Format("[DoOneTime] Error occured while invoking delegate. {0}", ex), "[OneTimer]"); 
       } 
       finally 
       { 
        ((TimerDisposer)myTdToKill).InternalTimer.Dispose(); 
       } 
      }, 
         td, dueTime, TimeSpan.FromMilliseconds(-1)); 

      td.InternalTimer = timer; 
     } 
    } 

    class TimerDisposer 
    { 
     public Timer InternalTimer { get; set; } 
    } 

回答

0

我用你的第一個方法多次,效果很好。

第二個解決方案似乎是一次性事件的基於時間的觸發器的通用封裝。如果您正在查看經常性事件,那麼這種方法對我而言似乎不必要的複雜,並且從增加的複雜性中沒有獲得明顯的好處。

+0

謝謝,我剛剛更新了一個潛在的問題...冒充的問題。 – LamonteCristo 2011-01-19 17:53:28

相關問題