VB.NET Application freezes when minimizing

881 Views Asked by At

I have a windows forms application consisting of a single form which parses a large body of text upon clicking a few buttons.

There is a huge chunk of code which parses through every node of an XML file, typically around 5000 nodes containing 20-ish child nodes, and those have even more children, and so on and so forth, just to create an image of the file's size.

While iterating through the code, as in when the data is being parsed, if I press the minimize button, it won't minimize but goes into the "not responding" state. My guess is that the minimize function can't be processed while the data is being parsed.

Is there a way to set an interrupt to the minimize/maximize/close buttons, or set priority to them, or any other solution to enable smooth minimisation of the form?

Thanks in advance

2

There are 2 best solutions below

1
On

Since you are parsing your XML in your main thread, the GUI can't update until the parsing is finish. The best option is to use the BackgroundWorker. It will start an other thread that permit you to execute the parsing of your file while leaving the GUI responsive to the user input.

3
On

Sorry to add almost the same answer as Stephan, but waited 10 hours for him to remove the DoEvents thing.

Data gathering or parsing should be handled in another Thread. The simpliest way is to use a BackgroundWorker, and implementing at least two event handlers :

BGWorker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
' Move your parsing code here
' use local variables whenever possible
' do the appropriate changes

' and
BGWorker_RunWorkerCompleted( _
    ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
' tells your Main thread that it can use the resuls

Note :
You must be careful not to manipulate any user-interface objects in your DoWork event handler. Instead, communicate to the user interface through the ProgressChanged and RunWorkerCompleted events.


And I would add :
Everything your BGW needs in its DoWork should remain untouched (*) by any other code. The DoWork() can access anything in your main thread (ex : manipulating a class instance of FileContent, calling a Function, reading a static variable...) You shouldn't take that lightly ! This could produce unexpected behaviours due to interference like multiple Workers, states changes or User inputs.

User inputs interfering with the parsing process should be handled : use the .RunWorkerCompleted(..) to capture when your main thread can safely (let user) access and manipulate datas, change states, etc.

(*) Best move is to make everything required by your BGW as a copy of the actual values at the beginning of the work. If you have a very long task to do, and states changes could occur in the meantime (ex : filesystem hierachy + file deletion - date changing while running a code that orders results by time...) you should :

  • either think again, whether all the required tools are available in your code to properly complete the task (best case)
  • either carefully handle the .Error Property of the RunWorkerCompletedEventArgs parameter (then fix the error, and try again..)
  • either validate your data integrity prior to use them (worst scenario)

EDIT : BGW is not the only way. Have a look at Threads and Threading while following Managed Threading Best Practices advices.