C # / WPF - CurrentDispatcher и DispatchTimer - Исключение параллельной модификации с очень частотой - PullRequest
1 голос
/ 21 июня 2011

У меня есть WPF GUI, который выдает определенную ошибку, возможно, один раз в день.

“Collection was modified after the enumerator was Instantiated"

Конкретная коллекция, на которую она ссылается, это Dictionary of TimeStamps.'dict' является закрытой переменной-членом.

dict = new Dictionary<string, List<DateTime>>();

Существует два места, на которые ссылается Collection, оба должны вызываться только в потоке диспетчеризации.Первое место предназначено для добавления в словарь и вызывается при изменении определенного свойства DependencyProperty в ViewModel:

void CalledFromDispatch(Item i)
{
   dict[i.Category].Add(DateTime.UtcNow);
}

Во втором месте я читаю из словаря.Выдающимся является свойство зависимости bool.

void PeriodicUpdate()
{
    HasOutstanding = dict["New"].Any(); 
}

Назначение HasOutstanding - это то, где генерируется исключение, я знаю, что могу использовать Count > 0 для решения проблемы, но меня беспокоит, что исключение возможно.

Первый фрагмент кода по сути называется так:

Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.DataBind, () => CalledFromDispatch(i));

Второй запланирован так:

DispatcherTimer DispatcherTimer = new DispatcherTimer(DispatcherPriority.DataBind)
DispatcherTimer.Interval = TimeSpan.FromSeconds(1);
DispatcherTimer.Start();
  ...
DispatcherTimer.Tick += (s, e) => PeriodicUpdate();

Так что мои вопросы кипятвплоть до;

  • Использует ли DispatchTimer тот же поток, что и CurrentDispatcher?
  • Если это так, возможно ли, чтобы диспетчер мог переключать запланированную операцию в середине выполнения?

В противном случае я не знаю, как это происходит.

Мне бы очень хотелось узнать больше о том, как DispatchTimer взаимодействует с CurrentDispatcher.Если у кого-то есть ресурс, который может помочь прояснить ситуацию, я буду очень признателен за ссылку.

1 Ответ

2 голосов
/ 21 июня 2011

При условии, что оба они были вызваны / setup в потоке пользовательского интерфейса, все должно быть в порядке.

Я подозреваю, что вы используете BeginInvoke неправильно.Dispatcher.CurrentDispatcher - это Dispatcher для "потока, выполняемого в данный момент", не Диспетчера потока пользовательского интерфейса.Скорее всего, вам нужно изменить это на что-то вроде Application.Current.Dispatcher.BeginInvoke (Диспетчер, связанный с текущим Приложением) или какой-либо Диспетчер UIElement.

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