C#/ WPF - 当前Dispatcher和DispatcherTimer - 非常频繁的并发修改异常

时间:2011-06-21 16:36:23

标签: c# wpf thread-safety

我有一个WPF GUI,可能每天抛出一次特定的错误。

“Collection was modified after the enumerator was Instantiated"

它所引用的特定集合是TimeStamps字典。 'dict'是一个私有成员变量。

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

有两个地方引用了Collection,只有应该才能在调度线程上调用。第一个位置用于添加到字典中,并在ViewModel上的特定DependencyProperty更改时调用,

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相同的线程?
  • 如果是这样,Dispatcher是否可能在执行期间切换计划的操作?

否则我不知道这是怎么发生的。

我真的很想了解更多有关DispatchTimer如何与CurrentDispatcher交互的信息。如果有人有资源可能有助于澄清情况,那么我非常感谢这个链接。

1 个答案:

答案 0 :(得分:2)

如果这两个都在UI线程上调用/设置,那应该没问题。

我怀疑你是否错误地使用了BeginInvokeDispatcher.CurrentDispatcher是“当前正在执行的线程”的Dispatcher不是 UI线程的Dispatcher。您很可能需要将其更改为Application.Current.Dispatcher.BeginInvoke(与当前应用程序关联的Dispatcher)或某些UIElement的Dispatcher。