【问题标题】:Using ElapsedEventHandler for automatically remove element from a collection使用 ElapsedEventHandler 自动从集合中删除元素
【发布时间】:2015-02-19 14:31:46
【问题描述】:

我想实现一个集合(ListDictionary),它的条目会在一段时间后过期:当条目过期时,它应该自动从集合中删除。

我看了this question的回答,建议使用后台线程来检查和删除过期的项目。相反,this answer 中提出的解决方案涉及使用Timer

由于Timer 是在一个单独的线程上调用的,那么就性能而言,使用第二种解决方案比第一种解决方案有什么优势?

【问题讨论】:

  • 这是一个非常危险的代码,它修改了 List 而没有用锁保护它。 List 不是线程安全的,它迟早会变坏。

标签: c# .net multithreading timer


【解决方案1】:

定时器通常比将整个线程专用于任务更可取,因为它们通常是通过允许共享相关线程的某种机制实现的。例如,System.Windows.Forms.Timer 类使用 WM_TIMER windows 事件,这是一个自动生成的事件,当计时器间隔过去时,您的 UI 线程的消息泵将接收到该事件(即,计时器事件始终在 UI 线程中引发)。 System.Threading.TimerSystem.Timers.Timer 计时器使用单个(或少量)线程来管理多个计时器。

根据您的情况,使用System.Windows.Forms.Timer 类的优势(如上所述):在 UI 线程中引发 elapsed 事件。如果您的集合以某种方式绑定到 UI 并且因此对其进行更改也需要更新 UI,这可能会很有用。

如果该优势适用于您,并且您使用的是 .NET 4.5,我建议在 async 方法中使用 Task.Delay() 方法,因为恕我直言,这是实现相同行为的更易读的方法。

事实上,即使在不需要在 UI 线程中引发 elapsed 事件的其他场景中,您实际上也可以使用 Task.Delay();在这种情况下,如果从 UI 线程调用,您需要将 .ConfigureAwait(false) 添加到调用中,以便 Task 库不会浪费精力在 UI 线程上执行延续(可能不会有任何伤害,但是不需要的时候最好还是不要)。

请注意,以上都是相当广泛的概括。如果没有关于您的具体场景的具体细节,真的不可能提供比这更具体的任何东西。

【讨论】:

    猜你喜欢
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 2021-05-05
    • 1970-01-01
    • 2012-05-13
    • 2017-08-23
    • 1970-01-01
    相关资源
    最近更新 更多