As suggested by @Piotr, you can make use of BackgroundWorker thread to achieve this.
As a reasoning why your code is not working, the btn click handler runs on UI thread and you happen to be doing all the work in the same (UI) thread which mean UI thread doesn't get to paint changes in Busy Indicator.
while Application.DoEvents() helps in a force repaint, it should be avoided and the right way to achieve this is delegating all work to a background thread (you can also use ThreadPool.QueueUserWorkItem) and marshal all changes to UI object/properties to UI thread by using Control.BeginInvoke/Control.Invoke.
Since, any changes to a UI object could only be done on a UI thread you will have to marshal such updates by using Control.Invoke etc.
BackgrounWorker class encapsulates this marshalling by providing differenet event handlers. From memory, I thin ProgressChanged and Completed handlers are invoke on UI thread. So you can safely update your UI control within these handlers and do the time consuming work in DoWork handler.
Update: Here is good explanation on why DoEvents is Evil.