I'm writing (my first) WPF app that searches the web and displays links in a ListBox. In order to speed everything up I'm using multiple threads to download the links. However, I've run into an interesting multi-threading dilemma:
Suppose I have the UI thread and then another 开发者_JS百科2 threads spawned to download links. Now the download threads add links to a List
called LinkList
which my ListBox
is bound to. If Thread1 updates LinkList
then the UI thread tries to iterate over the LinkList
to rebind the ListBox
. If, while the UI thread is iterating, Thread2 tries adding items to LinkList
, an exception is thrown on the UI thread because you can't add an item to a list while iterating.
I don't want to have to wait until all threads return to bind the ListBox since that means the user has to wait a long time. Is there a pattern to handle this? Can I somehow put a lock
around the iteration on binding on the UI thread?
INotifyCollectionChanged isn't thread safe (unline INotifyPropertyChanged) so you should use the dispatcher to add items from the UI thread instead when adding items to your LinkList from a worker thread
var objectToAdd = ...
Dispatcher.Invoke(new Action(() =>
{
LinkList.Add(objectToAdd);
}));
精彩评论