c# - Getting around "Collection was modified; enumeration operation may not execute" with async - i.e. without locking -
i have ui displaying graphs held in observable collection. user can change time span graphs referencing - there's listener triggers loop through them , re-fetches data, can take while.
foreach (timeseriesdataviewmodel viewmodels in trends) { viewmodels.timeseriesdatamodel = await modelprovider.gettimeseriesdatafor(viewmodels.kpiviewmodel.kpimodel, timespanviewmodel.starttime, timespanviewmodel.endtime); }
my problem is, while happening user can modify collection adding more trends, or deleting them. results in "collection modified; enumeration operation may not execute" exception.
normally, i'd doing using background process, , i'd put lock around accessing collection. however, locks don't work asynchronous code (which i'm new to!). there standard way of doing this?
i'm using thread safe concurrent observable collections here.
edit:
after experimentation, seems work well. however, i'm lucky don't need await removing items, can keep await outside await lock statements.
concurrentdictionary<itimeseriesdataviewmodel,task<itimeseriesdatamodel>> updatedatatasks = new concurrentdictionary<itimeseriesdataviewmodel,task<itimeseriesdatamodel>>(); lock (trends) { foreach (itimeseriesdataviewmodel viewmodels in trends) { updatedatatasks.getoradd(viewmodels, modelprovider.gettimeseriesdatafor(viewmodels.kpiviewmodel.kpimodel, timespanviewmodel.starttime, timespanviewmodel.endtime)); } } await task.whenall(updatedatatasks.values); foreach (keyvaluepair<itimeseriesdataviewmodel, task<itimeseriesdatamodel>> item in updatedatatasks) { item.key.timeseriesdatamodel = item.value.result; }
the problem lock can't contain await, data before awaiting?
Comments
Post a Comment