Вот метод, который повторно вызывает действие в фоновом потоке, прерывает и перезапускает поток каждый раз, когда истекает крайний срок. Он также принимает CancellationToken
для обеспечения преждевременной отмены процедуры (до окончания программы).
private static void RepeatInBackgroundThread(Action action, int timeout,
CancellationToken cancellationToken)
{
var timer = new System.Timers.Timer(timeout);
timer.AutoReset = false; // to raise the Elapsed event only once
var thread = new Thread(() =>
{
while (true)
{
if (cancellationToken.IsCancellationRequested) return;
timer.Start();
action();
timer.Stop();
}
});
timer.Elapsed += (sender, e) =>
{
thread.Abort();
thread.Join(); // Wait for the thread to die
if (cancellationToken.IsCancellationRequested) return;
RepeatInBackgroundThread(action, timeout, cancellationToken);
};
thread.IsBackground = true;
thread.Start();
}
Пример использования:
var random = new ThreadLocal<Random>(() => new Random());
var cts = new CancellationTokenSource();
RepeatInBackgroundThread(() => Thread.Sleep(random.Value.Next(0, 1000)), 500, cts.Token);
RepeatInBackgroundThread(() => Thread.Sleep(random.Value.Next(0, 200)), 100, cts.Token);
RepeatInBackgroundThread(() => Thread.Sleep(random.Value.Next(0, 100)), 50, cts.Token);
//cts.CancelAfter(10000);
Следует отметить, что прерывание потоков не является хорошей практикой в целом.