簡體   English   中英

Javascript 在 c# 中的 SetTimeout、SetInterval 和 ClearInterval 等價物

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM