The first thing that springs to mind is that it would probably be better to not create the
StreamReader instances when it can be avoided simply by using the
File.ReadAllText method to accomplish the same goal:
public void ProcessFile(string filename)
In other situations you might need to avoid this, especially for very large files. For small files and simple operations the
File.Read... methods should suffice.
Main advantage is that you relegate the object management issues to the framework, reducing the complexity of your code. This should result in fewer bugs and greater readability.
For larger files, especially where you are wanting to process individual lines (a common use case) it is often useful to use the
File.ReadLines method to process the content. This should read the lines as needed with some buffering, reducing memory consumption while maintaining code simplicity.
On the question of exception handling... I prefer to only put exception handling in when it is required by the specific situation, and I didn't see a specific need here. If the idea of an exception breaking out of this code concerns you then by all means add some in. Personally I'd prefer to have the exception bubble out than have to write all the extra code in here to not only handle the exception but also change what we do with a null return, etc.
In general I don't like the idea of always trying to catch exceptions as soon as possible. I prefer to catch as soon as I need to and no sooner.