【问题标题】:Is timer (thread) discarded with monitor.tryenter or it will be executed later?定时器(线程)是用 monitor.tryenter 丢弃还是稍后执行?
【发布时间】:2015-07-31 20:12:04
【问题描述】:

我想确保以下代码没有可重入性。还想知道未重新进入的线程是否稍后执行(我希望它们被丢弃)。 如果第一个计时器没有完成,下一个计时器会在它完成后立即触发还是会额外等待 15 毫秒?

谢谢

public void MainFunction(IntPtr h, List<int> a)
    {
        myTimer= new System.Timers.Timer();

        myTimer.Elapsed += delegate { eventfired(h, a); };
        myTimer.Interval = 15;
        myTimer.Start();
    }
    private void eventfired(IntPtr h, List<int> a)
    {
        if (System.Threading.Monitor.TryEnter(syncThreads))
        {
            try
            {
                DoWork()

            }
            finally
            {
                System.Threading.Monitor.Exit(syncThreads);
            }
        }
    }

我不确定这是最好的方法还是 autoreset= false 并在回调后启动计时器更好。

关键是:当时只有一个线程在工作,如果旧线程仍在工作,则丢弃创建的线程。

【问题讨论】:

  • 没有意义,使用 AutoReset = false 代替。不需要锁,不需要让线程池忙于无用。并迫使您在 Elapsed 事件处理程序中考虑 try/catch,它是 not 可选的。

标签: c# multithreading timer monitor


【解决方案1】:

这行得通。使用 TryEnter(ref bool) 重载,因为它在出现异常时更安全。

如果第一个计时器没有完成,下一个计时器会立即被解雇

为什么会这样。计时器不知道你在做什么。它只是将计时器滴答排入线程池。您的 TryEnter 代码可以消除冲突。

可能会巧合地发生多个计时器滴答声一个接一个地执行,以便您的代码连续多次运行而不会延迟。

【讨论】:

  • 你是说,这个? msdn.microsoft.com/en-us/library/dd289679(v=vs.110).aspx? “它引发碰撞”是什么意思?另外,当我打开lockdowork() 正在被另一个人执行)时,有没有办法不排队计时器,而是删除/删除/返回它们?如果不可能,我想我可以在dowork() 之前添加一个变量以确保它必须工作。否则,只能退货。但也许有更干净的方法来做到这一点?谢谢!
  • 是的,正确的过载。现在“重复”计时器滴答声没有被执行。我以为这就是你想要的?如果你想对它们进行排队,要么正常使用lock,要么维护一个错过滴答声的计数器。
  • 这就是我想要的。重复的计时器(= 在回调函数上创建的新计时器)应该被丢弃。现在和以后都没有执行。从你之前的回答中不明白你的意思。所以,如果我在 tryenter 里面,新的计时器根本不会被执行,对吧?谢谢,我改变了我的重载tryenter方法。
猜你喜欢
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 2019-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多