2011-01-19 5 views
2

SOを広く読んだら、Thread.Sleepa bad ideaです。代わりに、一般的な合意は、サーバー側のタスクはTimerthreadpool、またはJoin()を使用する必要があります。Timer、ThreadPool、AutoResetEvent、または "偽装"を使用する必要がありますか?

1つのarticleにはタイマーの処理が難しいと記載されています。

別の質問

30秒ごと、1分、または5分を繰り返すことになります長時間実行されるタスクを起動する際に使用する権利のアプローチはどのようなものですwaitOne

使用して言及article?制約は、前のタスクの実行が間隔(32秒または7分)より長い場合、その前のインスタンスを強制終了するか、新しいインスタンスを実行しないかのいずれかを選択する必要があるという制約があります。

潜在的な問題は、これらのスレッドでWindowsImpersionationContext、P/Invoke 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

私はあなたの最初のアプローチを何回も使用しており、うまくいきます。

第2の解決策は、ワンタイムイベントの時間トリガの一般的なカプセル化であるように見えます。あなたが定期的なイベントを見ているなら、このアプローチは不必要に複雑で、複雑さが増しても明らかなメリットは得られません。

+0

ありがとう、私はちょうど潜在的なつかみと質問を更新しました...偽装。 – LamonteCristo

関連する問題