C# “四处走动”;收集被修改;枚举操作不能执行";带异步-即不带锁定

C# “四处走动”;收集被修改;枚举操作不能执行";带异步-即不带锁定,c#,asynchronous,C#,Asynchronous,我有一个UI,显示一些保存在可观察集合中的图形。用户可以更改所有图形所引用的时间跨度-有一个侦听器,然后触发它在这些图形中循环并重新获取数据,这可能需要一段时间 foreach (TimeSeriesDataViewModel viewModels in Trends) { viewModels.TimeSeriesDataModel = await modelProvider.GetTimeSeriesDataFor(viewModels.KPIViewModel.KPIModel,

我有一个UI,显示一些保存在可观察集合中的图形。用户可以更改所有图形所引用的时间跨度-有一个侦听器,然后触发它在这些图形中循环并重新获取数据,这可能需要一段时间

foreach (TimeSeriesDataViewModel viewModels in Trends)
{
    viewModels.TimeSeriesDataModel = await modelProvider.GetTimeSeriesDataFor(viewModels.KPIViewModel.KPIModel,
                                                                                TimeSpanViewModel.StartTime,
                                                                                TimeSpanViewModel.EndTime);
}
我的问题是,当这种情况发生时,用户可以通过添加或删除更多趋势来修改集合。这导致“集合已修改;枚举操作可能无法执行”异常

通常情况下,我会使用后台进程执行此操作,并在访问集合的周围设置一个锁。但是,锁不适用于异步代码(我是新手!)。有没有标准的方法来做这样的事情

我使用的是来自的线程安全并发可观察集合

编辑:

经过一些实验,这似乎很有效。然而,我很幸运,我不需要等待移除项目,因此我可以将等待始终保持在等待锁语句之外

        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;
        }
ConcurrentDictionary updateDataTasks=新建ConcurrentDictionary();
锁定(趋势)
{
foreach(趋势中的ItimeSriesDatViewModel视图模型)
{
updateDataTasks.GetOrAdd(viewModels,modelProvider.GetTimeSeriesDataFor(viewModels.KPIViewModel.KPIModel,
TimeSpanViewModel.StartTime,
TimeSpanViewModel.EndTime);
}
}
wait Task.WhenAll(updatedatask.Values);
foreach(updateDataTasks中的KeyValuePair项)
{
item.Key.TimeSeriesDataModel=item.Value.Result;
}
问题是锁不能包含等待,所以在等待之前获取数据