У меня есть приложение xamarin для Android. Я постоянно получаю сообщение об ошибке, связанной с изменением коллекции или ошибкой нулевой ссылки, и думаю, что это связано с многопоточностью в приложении.
Мой объект, который используется как поле в и извлекается из статического класса State при необходимости:
public static State {
public ResultSet events { get; set; }
}
public class ResultSet {
public List<Event> all { get; set; }
public List<Event> activeEvents { get; private set; }
public List<Event> flaggedEvents { get; private set; }
public List<Event> inactiveEvents { get; private set; }
public void AddEvent(Event e) {
all.Add(e);
RecalculateResultSets();
}
public void InactivateEvents(List<Event> events) {
foreach (var event in events) {
event.isActive = 0;
}
RecalculateResultSets();
}
private RecalculateResultSets() {
activeEvents = all.Where(e => e.isActive = 1);
inactiveEvents = all.Where(e => e.isActive = 0);
flaggedEvents = all.Where(e => e.isflagged = 1);
}
}
Я получаю ошибки в других частях моего приложения для Android, когда звоню:
var _events = state.events.activeEvents.Where(...)
или
var _events = events.activeEvents.Sort(...)
У меня есть много различных методов в классе ResultSet, таких как InactivateEvents (), AddEvents (), DeleteEvents (), UpdateActiveState () и т. Д., Которые влияют на поле «all», а другие обновляются на основе этого.
Нужно ли устанавливать блокировку «all» и снимать ее после запуска RecalculateResultSets в каждом из этих методов? Нужна ли также блокировка для activeEvents и т. Д., Чтобы они не читались во время обновления RecalculateResultSets?
Обновление:
Я рассмотрел использование ConcurrentDictionary, но моя проблема в том, что в списке есть сохраненные и несохраненные события, и все несохраненные события имеют идентификатор 0. ConcurrentBag, похоже, будет проблемой, потому что мне нужен список, упорядоченный по дата.