Многопоточность объекта с общедоступным сет-листом и приватным сет-подсписком - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть приложение 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, похоже, будет проблемой, потому что мне нужен список, упорядоченный по дата.

1 Ответ

0 голосов
/ 13 сентября 2018

Не видя трассировки стека, немного сложно определить ошибку.

Вы можете попробовать заменить свой список на ConcurrentDictionary для решения нескольких проблем с многопоточностью.

Вы также можете попробовать блокировку объекта, чтобы заблокировать доступ к одному потоку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...