In many cases I need to use these functions in C#. My projects has to be .NET 4.0 and following code is the result that I was able to write after reading questions and answers about these functions. I have been using them for a while and didn't have any problems. However, playing with threads is dangerous so I have a doubt if I'm doing it wrong or not.
My question is, are these functions are safe to use; or is there a better way to do it for .NET 4.0?
private static volatile List<System.Threading.Timer> _timers = new List<System.Threading.Timer>();
private static object lockobj = new object();
public static void SetTimeout(Action action, int delayInMilliseconds)
{
System.Threading.Timer timer = null;
var cb = new System.Threading.TimerCallback((state) =>
{
lock (lockobj)
_timers.Remove(timer);
timer.Dispose();
action();
});
lock (lockobj)
_timers.Add(timer = new System.Threading.Timer(cb, null, delayInMilliseconds, System.Threading.Timeout.Infinite));
}
private static volatile Dictionary<Guid, System.Threading.Timer> _timers2 = new Dictionary<Guid, System.Threading.Timer>();
private static object lockobj2 = new object();
public static Guid SetInterval(Action action, int delayInMilliseconds)
{
System.Threading.Timer timer = null;
var cb = new System.Threading.TimerCallback((state) => action());
lock (lockobj2)
{
Guid guid = Guid.NewGuid();
_timers2.Add(guid, timer = new System.Threading.Timer(cb, null, delayInMilliseconds, delayInMilliseconds));
return guid;
}
}
public static bool ClearInterval(Guid guid)
{
lock (lockobj2)
{
if (!_timers2.ContainsKey(guid))
return false;
else
{
var t = _timers2[guid];
_timers2.Remove(guid);
t.Dispose();
return true;
}
}
}
In many cases I need to use these functions in C#. My projects has to be .NET 4.0 and following code is the result that I was able to write after reading questions and answers about these functions. I have been using them for a while and didn't have any problems. However, playing with threads is dangerous so I have a doubt if I'm doing it wrong or not.
My question is, are these functions are safe to use; or is there a better way to do it for .NET 4.0?
private static volatile List<System.Threading.Timer> _timers = new List<System.Threading.Timer>();
private static object lockobj = new object();
public static void SetTimeout(Action action, int delayInMilliseconds)
{
System.Threading.Timer timer = null;
var cb = new System.Threading.TimerCallback((state) =>
{
lock (lockobj)
_timers.Remove(timer);
timer.Dispose();
action();
});
lock (lockobj)
_timers.Add(timer = new System.Threading.Timer(cb, null, delayInMilliseconds, System.Threading.Timeout.Infinite));
}
private static volatile Dictionary<Guid, System.Threading.Timer> _timers2 = new Dictionary<Guid, System.Threading.Timer>();
private static object lockobj2 = new object();
public static Guid SetInterval(Action action, int delayInMilliseconds)
{
System.Threading.Timer timer = null;
var cb = new System.Threading.TimerCallback((state) => action());
lock (lockobj2)
{
Guid guid = Guid.NewGuid();
_timers2.Add(guid, timer = new System.Threading.Timer(cb, null, delayInMilliseconds, delayInMilliseconds));
return guid;
}
}
public static bool ClearInterval(Guid guid)
{
lock (lockobj2)
{
if (!_timers2.ContainsKey(guid))
return false;
else
{
var t = _timers2[guid];
_timers2.Remove(guid);
t.Dispose();
return true;
}
}
}
Share
Improve this question
asked Nov 9, 2016 at 8:26
KorayKoray
1,8061 gold badge28 silver badges39 bronze badges
3
-
JS hasn't timers,
setTimeout
andsetInterval
are DOM methods. – Teemu Commented Nov 9, 2016 at 8:33 - 1 @Teemu - don't be overly-pedantic, you know what the OP meant. – user1017882 Commented Nov 9, 2016 at 9:16
- @JᴀʏMᴇᴇ The ment was not meant overly-pedantic. Just saying, that timers are not built-in features in JavaScript. That might be useful, when trying to find similar features from other languages. – Teemu Commented Nov 9, 2016 at 9:33
3 Answers
Reset to default 8This is how I implement Javascript's setTimeout and clearTimeout functions in C# using Task Parallel Library (TPL):
SetTimeout:
public CancellationTokenSource SetTimeout(Action action, int millis) {
var cts = new CancellationTokenSource();
var ct = cts.Token;
_ = Task.Run(() => {
Thread.Sleep(millis);
if (!ct.IsCancellationRequested)
action();
}, ct);
return cts;
}
ClearTimeout:
public void ClearTimeout(CancellationTokenSource cts) {
cts.Cancel();
}
How to use:
...
using System.Threading;
using System.Threading.Tasks;
...
var timeout = SetTimeout(() => {
Console.WriteLine("Will be run in 2 seconds if timeout is not cleared...");
}, 2000);
And if you want to cancel the action before it's run:
ClearTimeout(timeout);
Libraries to use
...
using System;
using System.Threading.Tasks;
...
The function itself
...
private void setTimeout(Func<int> function, int timeout) // Take in a callback and a timeout
{
Task.Delay(timeout).ContinueWith((Task task) => // Use Task to delay the function by the timeout, then call the function "function"
{
function();
});
}
...
An example on how to use it
...
setTimeout(() =>
{
Console.WriteLine("After 1 second");
return 0; // By the way, don't miss this line, because or else you'll get an error of not fitting in Function<int>
}, 1000);
...
Only drawback I could find so far is, if there are running actions, the application cannot exit. While ending the application this function should be called:
public static void Free()
{
lock (lockobj)
{
foreach (var t in _timers)
t.Dispose();
_timers.Clear();
}
lock (lockobj2)
{
foreach (var key in _timers2.Keys.ToList())
ClearInterval(key);
}
}