For clarification let me remind you that the BWC is not for updating the UI on a background thread but instead for doing work on a background thread and then updating the UI thread with the results. So when you say that you are doing the update in the BWC thread don't you really mean you are doing your non-UI processing in the BWC and then calling ReportProgress to update the grid on the UI thread? You can not, under any circumstances, update the UI on any thread other than the thread that created it. This is a common flaw in people's thinking of the UI. Many people believe that if they have to update the UI and it'll take 10 seconds to do so then they should use a secondary thread but that is incorrect. If it takes you 10 seconds to update a UI then it will still take that long irrelevant of threading. Only the non-UI work can be pushed to a background thread. Assuming we are on the same page here can you specify what work you're doing on the UI side when the progress changed event is raised? A summary of the work done in the BWC thread would also be useful.
As a side note please be aware that a marquee in absolutely no way conveys to a user that the program has not hung. We have all sat at a wait cursor ora "cancelling operation" dialog with animation on a hung application. Using threading makes it more likely that your users will not be aware of a hung app rather than letting them know it has hung. Because the UI will continue to pump messages even if we put our secondary thread into an infinite loop.
If your grid takes a long time to update then you might want to consider an alternative UI instead. Using paging you can dramatically cut down on the data to be displayed. A grid with more than a screen full or two of data is not that useful and just confuses users in general. Filtering and paging eliminate some of these issues. Using either also reduces the amount of time an update takes to occur and can remove the need for BWC (and your problem) altogether. Of course just caching the data (if it isn't too bad) also eliminates the need for a background update.
Another alternative is to use the BWC to update the data in the background but still allow the user to interact with the UI (aka no marquee). This is predominantly one of the strengths of BWC. This is especially useful if the operation takes a while because the user might not even care about the grid but would have to wait for the update anyway. It depends on how your application is laid out. If you go this route then you would update the grid in blocks (say 1, 5 or 10 rows at a time) as the data is processed on the background thread. Meanwhile the user can interact with the application and potentially cancel the updating process. You should provide some sort of indicator that the grid is still updating and when it completes so the user knows when it is safe to continue. The Add/Remove Progarms list in Vista (and maybe XP, can't remember) is an example on how NOT to do this. The GAC assembly list in Reflector is also an example of a bad way to do background updating. In both of these cases the user has no way to know when the list is finished populating so they don't know if the item they're looking for doesn't exist or just hasn't been displayed yet. But they do provide the cancellation option which is good since I don't need to see the entire list before I make a decision necessarily.
Michael Taylor - 10/25/07
http://p3net.mvps.org