It seems fine to me, apart from the fact that you don't need to start a task with Task.Factory.StartNew
. The System.Threading.Timer
already executes your callback on the ThreadPool, so there's no need to launch yet another task that will also be run on the thread pool.
Also, if your timer ticks every 5 seconds, and you expect it to take about 10 secs to process the files, then your threads will begin to queue up waiting for the lock to be released. That happened on the example you posted.
If this is the case, I would either increase the timer's period to more than 10 secs, or use Monitor.TryEnter
instead of a regular lock
. TryEnter
will try to acquire the lock, and return immediately regardless of whether or not the lock was taken. If the lock is currently taken by another thread, you just skip this tick entirely.