| | | | Browse by category |
Problem
Objective Grid and multiple threads
Cause
Action
You must not access grid operations from different threads at the same time. The grid maintains some internal attributes that are set while specific operations are performed. For example, when drawing the grid all the drawing information is cached in the grid. If you call a grid operation from a second thread while at the same time the grid does some other operation (for example, redrawing the grid or computing floating cells), the second operation could overwrite cached attributes of the first operation.
Therefore if you want to use a grid from different threads, you have to make sure that you never call grid operations from different threads at the same time. Use synchronization objects to avoid such a scenario.
Here is an answer that I posted recently in the newsgroup regarding this topic when I was asked how to fill the grid with data from multiple threads in background. You see there is still lots of room for discussion.
- Question: I have an application in which the processing of determining the cell values can take a while. I would like to have a worker thread fill in the values, leaving the main user-interface thread to handle painting and to remain responsive.
Answer: You must not perform grid operations from different threads at the same time. The grid maintains some internal attributes that are set while specific operations are performed. For example, when drawing the grid all the drawing information is cached in the grid. If you call a grid operation from a second thread while at the same time the grid does some other operation (for example, redrawing the grid or computing floating cells), the second operation could overwrite cached attributes of the first operation.
Therefore if you want to call grid operations from different threads, you have to make sure that you never call grid operations from different threads at the same time. Use synchronization objects to avoid such a scenario.
Regarding filling the grid, I recommend that you call StoreStyleRowCol() directly. StoreStyleRowCol() has the advantage that it will not force any drawing or other operations in the grid. When you call StoreStyleRowCol(), you might store info in a list to note which cells need to be redrawn or simply a flag that the whole grid should be eventually redrawn.
Of course, you also have to make sure that StoreStyleRowCol() is not called from different threads the same time and you have to use synchronization.
Once you have some processor time left, check that flag (or the list), protect the grid by using synchronization (so that any other grid operations and calls to StoreStyleRowCol() are blocked ), and redraw the grid.
Whenever you call grid operations, you have to check if it is allowed to call the grid and use synchronization.
In short:
Use synchronization to avoid multiple calls to StoreStylRowCol() at the same time and also make sure that StoreStylRowCol() is not called while the grid is drawing (here you can simply check m_bNestedDraw == 0 or again use another synchronization object).
I have to admit I am not a multi-threading expert and these are just my own ideas about how I think it should work. Let me know if you have problems or if my statements help you.