Я пытаюсь создать функцию, которая принимает действие и время ожидания, и выполняет действие после таймаута. Функция должна быть неблокирующей. Функция должна быть потокобезопасной. Я также очень хочу избавиться от Thread.Sleep().
Пока, самое лучшее, что я могу сделать, это:
long currentKey = 0;
ConcurrentDictionary<long, Timer> timers = new ConcurrentDictionary<long, Timer>();
protected void Execute(Action action, int timeout_ms)
{
long currentKey = Interlocked.Increment(ref currentKey);
Timer t = new Timer(
(key) =>
{
action();
Timer lTimer;
if(timers.TryRemove((long)key, out lTimer))
{
lTimer.Dispose();
}
}, currentKey, Timeout.Infinite, Timeout.Infinite
);
timers[currentKey] = t;
t.Change(timeout_ms, Timeout.Infinite);
}
Проблема заключается в том, что вызов Dispose() из самого обратного вызова не может быть хорошим. Я не уверен, что безопасно "упасть" с конца, т.е. Таймеры считаются живыми, пока их лямбды выполняются, но даже если это так, я бы предпочел правильно распоряжаться им.
"Огонь один раз с задержкой" кажется такой общей проблемой, что должен быть простой способ сделать это, возможно, в какой-то другой библиотеке в System.Threading я пропал без вести, но сейчас единственное решение, которое я могу придумать является модификацией вышеописанной задачи очистки, выполняемой с интервалом. Любые советы?