This problem is caused by having a loop. The web browser's navigation can only complete and the DocumentCompleted event can only fire when your UI thread goes idle again. This is core to the way multi-threaded components work, they can only fire their 'the job is done' event on the UI thread when the UI thread is idle and pumps the message loop. The BackgroundWorker class for example has the exact same requirement.
The proper way to solve it is to create a state machine. You kick it off by telling the browser to navigate to the first url. You let your DocumentCompleted event handler process the response and then tell the browser navigate to the next url. Or stop when there are no more urls to process.
The improper way is to call Application.DoEvents() in the loop. That pumps the message loop and allows the events to fire. But is a very dangerous thing to do, DoEvents() is not selective about exactly what events are processed. Be sure to read this answer if you contemplate using it anyway.
The next way is the upcoming support for the async and await keywords in the next version of C#. Currently available in CTP.