Just wondered what that best approach is for this scenario - trying to databind to a collection which is being populated in another background thread.
My background thread is adding items to the collection in a processing loop which may run for several minutes. Every now and then it raises an event to the UI and passes a reference to the data from the collection, for the UI to visualize, (so the user can start to interact with what they have) and carries on processing.
Trouble is the UI starts to render the visualisation (which is quite complex itself), which involves a foreach() loop over the collection of data, and understandably that loop craps itself if my background thread changes the data in the collection during the enumeration.
So my brainstorming has gone like this:
- pause the background thread; but I really don’t want to pause
- take a duplicate snapshot copy of all, or some the data in each event, and databind to the snapshot. Doubles my memory usage but would probably work
- implement some kind of lock{} on the syncroot or whatever of the collection so while the UI is updating the background process has to wait. Not 开发者_StackOverflow社区confident about that working anyway
- fire the event all the time and just pass one bit of data at a time, which has the same result as #2 but with more overhead..
cheers ewart.
The easiest way to fix your problem is by changing the foreach loop to a for loop that loops from 0 to the number of items in your collection before you start to loop.
instead of:
var coll = new List<string>();
foreach (string item in coll)
{
//do your stuff
}
use:
var coll = new List<string>();
int length = coll.Count - 1;
for (int i = 0; i < length; i++)
{
}
OR
I don't know how complex your UI is but with WPF you can almost always change the code to advanced databinding bound to an ObservableCollection. The Observable collection triggers an update of the binding when an item is added or removed. But to provide a solution for that requires a lot of information on how your UI is build.
精彩评论