不可重入定时器
我有一个函数,我想每 x 秒调用一次,但我希望它是线程安全的。
我可以在创建计时器时设置此行为吗? (我不介意使用哪个.NET 计时器,我只是希望它是线程安全的)。
我知道我可以在回调函数中实现锁,但我认为如果它在计时器级别会更优雅。
我的回调函数和环境与 UI 无关。
[编辑 1] 我只是不希望我的回调函数中有多个线程。
[编辑 2] 我想将锁定保留在计时器级别内,因为计时器负责何时调用我的回调函数,而这里有一种特殊情况,当我不想调用我的回调函数时。所以我认为何时调用是计时器的责任。
I have a function that I want to invoke every x seconds, but I want it to be thread-safe.
Can I set up this behavior when I am creating the timer? (I don't mind which .NET timer I use, I just want it to be thread-safe).
I know I can implement locks inside my callback function, but I think it would be more elegant if it were in the timer level.
My callback function, and environment are not related to a UI.
[Edit 1]
I just don't want there to be more than one thread inside my callback function.
[Edit 2]
I want to keep the locking inside the timer level, because the timer is responsible for when to call my callback, and here there is a particular situation when I don't want to call my callback function. So I think when to call is the responsibility of the timer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我猜测,由于您的问题并不完全清楚,您希望确保您的计时器在处理回调时无法重新输入回调,并且您希望在不锁定的情况下执行此操作。您可以使用 System.Timers.Timer 并确保 AutoReset 属性设置为 false 来实现此目的。这将确保您必须在每个时间间隔手动触发计时器,从而防止任何重入:
I'm guessing, as your question is not entirely clear, that you want to ensure that your timer cannot re-enter your callback whilst you are processing a callback, and you want to do this without locking. You can achieve this using a
System.Timers.Timer
and ensuring that theAutoReset
property is set to false. This will ensure that you have to trigger the timer on each interval manually, thus preventing any reentrancy:作为对 Tim Lloyd 针对
System.Timers.Timer
的解决方案的补充,这里有一个解决方案,用于在您想要使用System.Threading.Timer
的情况下防止重入。我相信您不希望在回调内部访问
interval
,但是如果您愿意,这很容易修复:将以上内容放入NonReentrantTimer
类中它包装了 BCL 的 Timer 类。然后,您可以将doSomeWork
回调作为参数传递。此类的一个示例:Complementing Tim Lloyd's solution for
System.Timers.Timer
, here's a solution to prevent reentrancy for cases where you want to useSystem.Threading.Timer
instead.I believe you don't want
interval
to be accessed inside of the callback, but that is be easy to fix, if you want to: Put the above into aNonReentrantTimer
class that wraps the BCL'sTimer
class. You would then pass thedoSomeWork
callback in as a parameter. An example of such a class:如果锁定是必要的那么计时器如何安排呢?您正在寻找神奇的免费赠品。
重新编辑1:
您的选择是System.Timers.Timer和System.Threading.Timer,两者都需要防止重新进入。请参阅此页面并查找处理计时器事件重入部分。
If locking is necessary then how could a timer arrange that? You're looking for a magical freebie.
Re Edit1:
Your choices are System.Timers.Timer and System.Threading.Timer, both need precautions against re-entrance. See this page and look for the Dealing with Timer Event Reentrance section.
计时器如何知道您的共享数据?
计时器回调在某些 ThreadPool 线程上执行。所以你至少有 2 个线程:
您有责任使用您的共享数据提供正确的工作。
重新编辑: chibacity 提供了完美的例子。
How timer could know about your shared data?
Timer callback is executed on some ThreadPool thread. So you will have at least 2 threads:
And it is your responsibility to provide correct work with your shared data.
Re edits: chibacity provided the perfect example.