0

I want to implement a collection (a List or a Dictionary) which has entries which expire after a while: when an entry is expired, it should be automatically removed from the collection.

I read the answer to this question, which proposed to use a background thread to check and remove the expired items. Instead, the solution proposed in this answer involves the use of Timer.

Since the Timer is invoked on a separate thread, what is the advantage of using the second solution than the first in terms of permormance?

Community
  • 1
  • 1
enzom83
  • 8,080
  • 10
  • 68
  • 114
  • It is very dangerous code, it modifies the List without protecting it with a lock. List is not thread-safe, that's going to byte badly sooner or later. – Hans Passant Feb 20 '15 at 00:08

1 Answers1

1

Timers are generally preferable to dedicating a whole thread to the task, because they generally are implemented via some mechanism that allows sharing of the thread in question. For example, the System.Windows.Forms.Timer class uses the WM_TIMER windows event, which is an auto-generated event that your UI thread's message pump will receive when the timer interval elapses (i.e. the timer event is always raise in the UI thread). The System.Threading.Timer and System.Timers.Timer timers use a single (or small number of) thread(s) to manage multiple timers.

Depending on your scenario, there is the advantage (noted above) to using the System.Windows.Forms.Timer class: that the elapsed event is raised in the UI thread. This could be useful if your collection is bound to the UI in some way and so changes to it require updating the UI as well.

If that advantage applies to you, and if you are using .NET 4.5, I would recommend using the Task.Delay() method in an async method instead, as IMHO it is a more readable way to implement the same behavior.

Indeed, you can in fact use Task.Delay() even in other scenarios where you don't need the elapsed event to be raised in the UI thread; in that case, if called from a UI thread you would want to add .ConfigureAwait(false) to the call, so that the Task library doesn't waste effort executing the continuation on the UI thread (probably wouldn't hurt anything, but when it's not needed, it's better not to anyway).

Note that the above is all fairly broad generalization. Without specific details on your precise scenario, it's not really possible to provide anything more specific than that.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136