System.Timers.Timer
のためにティム・ロイドのソリューションを補完するものとして、ここではあなたの代わりにSystem.Threading.Timer
を使用したい場合のために再入を防止するためのソリューションです。
TimeSpan DISABLED_TIME_SPAN = TimeSpan.FromMilliseconds(-1);
TimeSpan interval = TimeSpan.FromSeconds(1);
Timer timer = null; // assign null so we can access it inside the lambda
timer = new Timer(callback: state =>
{
doSomeWork();
try
{
timer.Change(interval, DISABLED_TIME_SPAN);
}
catch (ObjectDisposedException timerHasBeenDisposed)
{
}
}, state: null, dueTime: interval, period: DISABLED_TIME_SPAN);
私はあなたがinterval
は、コールバックの内側にアクセスすることにしたくないと考えているが、それはあなたがしたい場合は、修正することは容易である:BCLのTimer
クラスをラップNonReentrantTimer
クラスに上記を入れてください。その後、doSomeWork
コールバックをパラメータとして渡します。そのようなクラスの例:
public class NonReentrantTimer : IDisposable
{
private readonly TimerCallback _callback;
private readonly TimeSpan _period;
private readonly Timer _timer;
public NonReentrantTimer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period)
{
_callback = callback;
_period = period;
_timer = new Timer(Callback, state, dueTime, DISABLED_TIME_SPAN);
}
private void Callback(object state)
{
_callback(state);
try
{
_timer.Change(_period, DISABLED_TIME_SPAN);
}
catch (ObjectDisposedException timerHasBeenDisposed)
{
}
}
public void Dispose()
{
_timer.Dispose();
}
}
あなたが十分な情報を与えていない...は、プログラムの他の部分にはアクセスし、あなたの関数へのアクセスは何もしていますか?そうでない場合は、すでにスレッドセーフです(タイマーの有無にかかわらず)。はいの場合、タイマーはスレッドセーフでは何もありませんが、ロックなどを使用する必要があります。 – Yahia
**なぜ**ロックアウトを保持しますか?コールバック関数の正確な? –
@Paul - 私の編集を参照してください2 – Delashmate