FileSystemWatcher with threaded FIFO processing
Files created in the folder seem to be cached FileSystemWatcher until the current file has finished processing.


Not really cached, FileSystemWatcher just raises its events one at a time. So, until your event handler returns, you won't get another notification. And since you execute all your code in that event handler, that can take a very long time.

The docs say this:


  To avoid missing events, follow these guidelines:
  
  
  […]
  Keep your event handling code as short as possible.
  


So you shouldn't do it this way.




  Do I need two threads?


If you want to make reasonably sure you won't miss anything, yes, you need (at least) two threads.


  Is ObservableCollection the best object to use to manage the list of files to process?


In the current state, ObservableCollection doesn't make much sense, because there is no list, you will only ever have one item in the collection.

If you switched to two (or more) threads, ObservableCollection is still not a great choice, since it's not thread-safe.


  Where do I put a second thread? I am guessing that I need a new thread each time a new file is added to the ObservableCollection but won't that trigger a thread for each file, then the log will be jumbled up with each file that is added to the collection?


If you wanted to process each file in parallel, you would need more threads. To keep the log clean (and to perform any other operations that are not thread-safe), you should use a lock.

In any case, you shouldn't directly use Threads. Instead, you should use Tasks, or some higher-level constructs (see below for more), since they are more efficient and easier to work with.

But if you don't need parallelism, a single processing thread (i.e. two threads in total) is enough and it also means you don't need any locks (assuming only this thread writes to the log).



Some specific options on how you could implement this:


Use ActionBlock from TPL Dataflow (requires .Net 4.5). This could be the simplest option, since it means you don't need to create any Threads or Tasks manually.

In the event handler, you would call Post(), and the work would be handled by the delegate that you passed to ActionBlock's constructor.

ActionBlock can also work in parallel, if you set its MaxDegreeOfParallelism.
Use BlockingCollection and a Task with a loop.

In the event handler, you would call Add(). You would then also create a Task (using Task.Run() or Task.Factory.StartNew()) with a foreach loop over GetConsumingEnumerable(), that process the files.

This will work best if there is only a single Task, which means it won't be parallel.
Create a separate Task for each file.

In the event handler, you would create a Task with a delegate that processes the file.

This way, files will be processed in parallel.