When you write a Windows application, it starts with one thread - which means that it can do one thing at a time. If you are busy reading and processing lines from a file, then your application can't do anything else until you finish doing that - and that includes not responding to user input, or requests to change the display: because Windows works by sending messages to your app which it processes when it gets back to it's "idle loop" and looks for something to do. If you are keeping it busy looking at lines from files, then it never runs out of things to do and never looks at it's collection of messages.
So instead you need to start a second thread to do all the "donkey work" behind the scenes. But that introduces it's own problems, because you can only access display controls from a single thread - the UI thread that your app started with. If you try to change the text on a TextBox from a different thread for example, you will get a "Cross Threading Exception" and you app will fail. There are ways around that - it's called Invoking the control - but that gets complicated to explain.
So instead, look at the
BackgroundWorker Class (System.ComponentModel)[
^] - it allows you to very simply set up a second thread, and report progress events back to the main thread so it can update the controls to reflect it. Have a look at the example, and also at the ProgressChangedEventArgs as there is a UserState property which lets you send back complicated info on how the job is progressing to your main thread.