[英]JavaScript - setInterval / setTimeout & clearInterval, wont execute properly
[英]Javascript's SetTimeout, SetInterval and ClearInterval equivalent in c#
在許多情況下,我需要在 C# 中使用這些函數。 我的項目必須是 .NET 4.0,以下代碼是我在閱讀有關這些功能的問題和答案后能夠編寫的結果。 我已經使用它們一段時間了,沒有任何問題。 然而,玩線程是危險的,所以我懷疑我是否做錯了。
我的問題是,這些功能使用起來安全嗎? 或者有沒有更好的方法來為 .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;
}
}
}
這就是我使用任務並行庫 (TPL) 在 C# 中實現 Javascript 的 setTimeout 和 clearTimeout 函數的方式:
設置超時:
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;
}
清除超時:
public void ClearTimeout(CancellationTokenSource cts) {
cts.Cancel();
}
如何使用:
...
using System.Threading;
using System.Threading.Tasks;
...
var timeout = SetTimeout(() => {
Console.WriteLine("Will be run in 2 seconds if timeout is not cleared...");
}, 2000);
如果您想在運行之前取消操作:
ClearTimeout(timeout);
到目前為止我能找到的唯一缺點是,如果有正在運行的操作,應用程序將無法退出。 在結束應用程序時,應調用此函數:
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);
}
}
要使用的庫
...
using System;
using System.Threading.Tasks;
...
函數本身
...
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();
});
}
...
關於如何使用它的示例
...
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);
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.