Search code examples
.netmultithreadinguser-interfacebackgroundworker

GUI freeze while loading data in BackgroundWorker


I have a ListView control receiving data from BackgroundWorker through ReportProgress. The worker dumps about a hundred rows in a quick succession. Each chunk of data fires ProgressChanged event and GUI thread adds a new item to the ListView.

As the data retrieval operations run on a separate thread, the GUI is supposed to update on every change. But for some reason it doesn't happen - the interface remains frozen until the worker is completed.

Any ideas?

Also, the tests are done on very fast machine, so I don't think computer performance is an issue.

It's a WinForms application.


Solution

  • Put this in your BGW worker loop, after the ReportProgress call:

     System.Threading.Thread.Sleep(15);
    

    Odds are good that you now see the ListView updating. What's going on here is that the UI thread is getting flooded with delegate invoke requests. Which always get dispatched before the paint notification. If the next invoke request arrives before the previous one has finished running then it never gets around to doing the normal housekeeping tasks. Like painting and responding to input. The items actually do get added to the list view, you just can't see it being done.

    Call ReportProgress less often. Doing it more than 25 times per second is a waste of resources, no human can see the difference. Let the BGW store the items in a List<> and cut down on the UI thread overhead by calling AddRange().