SOを広く読んだら、Thread.Sleep
はa bad ideaです。代わりに、一般的な合意は、サーバー側のタスクはTimer
、threadpool
、または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; }
}
ありがとう、私はちょうど潜在的なつかみと質問を更新しました...偽装。 – LamonteCristo