【问题标题】:Javascript's SetTimeout, SetInterval and ClearInterval equivalent in c#c# 中 Javascript 的 SetTimeout、SetInterval 和 ClearInterval 等效项
【发布时间】:2016-11-09 08:26:26
【问题描述】:

在很多情况下,我需要在 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;
                }
            }
        }

【问题讨论】:

  • JS 没有定时器,setTimeoutsetInterval 是 DOM 方法。
  • @Teemu - 不要过于迂腐,你知道 OP 的意思。
  • @JᴀʏMᴇᴇ 该评论并非过于迂腐。只是说,计时器不是 JavaScript 的内置功能。在尝试从其他语言中查找类似功能时,这可能很有用。

标签: javascript c#


【解决方案1】:

这就是我使用任务并行库 (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);

【讨论】:

    【解决方案2】:

    到目前为止,我发现的唯一缺点是,如果有正在运行的操作,应用程序将无法退出。结束应用程序时,应调用此函数:

        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);
            }
        }
    

    【讨论】:

      【解决方案3】:

      要使用的库

      ...
      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);
      ...
      

      【讨论】:

      • 嗨,欢迎来到 SO !为了真正提供帮助,您能否就您的答案添加更多解释?
      • 我已经编辑了它,以便有解释
      猜你喜欢
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多