【问题标题】:Different behaviour of System.Timers.Timer and System.Threading.TimerSystem.Timers.Timer 和 System.Threading.Timer 的不同行为
【发布时间】:2013-08-06 06:07:48
【问题描述】:

首先我要说的是,这与其说是需要解决的问题,不如说是一个问题。我现在有了解决方案,对我来说一切正常。但我想知道为什么第一次出现问题。

这是我现在拥有的代码,它的工作方式与我预期的一样:

    private void OnNewGameStarted(Game game)
    {
        _activeGames.Add(game);

        TimeSpan delay = game.GetTimeLeft();
        var timer = new Timer(delay.TotalMilliseconds) {AutoReset = false};
        timer.Elapsed += (sender, args) => GameEndedCallback(game);
        timer.Start();
    }

    private void GameEndedCallback(Game game)
    {
        if (_statisticsManager.RegisterGame(game))
            _gamesRepository.Save(game);

        _gameStatusSubscriber.GameStatusChanged(game);
    }

我曾经使用 System.Threading.Timer 而不是 System.Timers.Timer,有时会触发计时器事件(GameEndedCallback 方法),有时不会。我找不到任何原因。

这是我用来初始化定时器的代码(其他部分相同):

            TimeSpan delay = game.GetTimeLeft();
            new Timer(GameEndedCallback,game,(int)delay.TotalMilliseconds,Timeout.Infinite);
        }

        private void GameEndedCallback(object state)
        {
            var game = (Game) state;

方法 OnNewGameStarted 是事件处理程序,当某些特定消息到达时,它会在 Fleck 网络服务器的方法链之后调用。

【问题讨论】:

标签: c# multithreading timer


【解决方案1】:

post 介绍了 3 种计时器类型及其作用。 主要是:

  • System.Timers.Timer 用于多线程工作
  • System.Windows.Forms.Timer - 来自应用程序 UI 线程
  • System.Threading.Timer - 并不总是线程安全的!

【讨论】:

  • 谢谢。我想我需要了解有关多线程的更多信息,以找出 System.Threading.Timer 失败的确切原因
  • 帖子现在是死链接。感谢微软神秘的“go-link”格式,不知道如何找到原始文章:(
【解决方案2】:

Timeout.Infinite 是回调调用之间的时间间隔,以毫秒为单位。指定 Timeout.Infinite 以禁用周期性信号。见 MSDN:http://msdn.microsoft.com/en-us/library/2x96zfy7.aspx Timeout.Infinite 是用于指定无限等待时间的常数。 试试这个以获得对回调的定期调用

new System.Threading.Timer(GameEndedCallback, game, (int)delay.TotalMilliseconds, (int)delay.TotalMilliseconds);

【讨论】:

  • OP 正在为每个游戏创建一个新的计时器实例。此外,游戏只能结束一次:)。此处不打算使用周期性信号。
  • "我曾经使用 System.Threading.Timer 而不是 System.Timers.Timer,有时会触发计时器事件(GameEndedCallback 方法),有时不会。我找不到任何原因为什么会这样。”未按问题调用回调
  • @user2323308 有时会被调用,所以我猜问题不在于定义适当的间隔和延迟
  • @AlexanderRomanov 不,如果您看到 MSDN。最后一个参数是“Period”,如果它具有“Timeout.Infinite”,则表示该周期是无限的。所以只有第一次被调用然后变成禁用
  • @user2323308 是的,这是预期行为:游戏只能结束一次。
猜你喜欢
  • 2010-11-27
  • 2013-11-03
  • 2011-06-25
  • 1970-01-01
  • 2016-04-17
  • 1970-01-01
  • 2013-10-07
  • 2018-01-03
  • 2019-04-10
相关资源
最近更新 更多