为什么当我传递参数时调度程序会这样?

Why is the dispatcher behaving this way when I pass a parameter?

我在 WPF 中使用 DataGridView。 在 RowEditEnding 事件中,我获取旧行(编辑结束前),然后通过调度程序调用方法获取新行(编辑后)

private void myGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
    DataRowView oldRowView = e.Row.Item as DataRowView;
    DataRow oldRow = oldRowView.Row;
    //When I put a breakpoint before the dispatcher is called, oldRow has the old row values. 
    Dispatcher.BeginInvoke(new Action(() => OnRowEdit(oldRow, e)), System.Windows.Threading.DispatcherPriority.Background);
    //I have now passed the old row to OnRowEdit
}

void OnRowEdit(DataRow oldRow, DataGridRowEditEndingEventArgs e)
{
  //Here oldRow has new row values. 
}

调用方法前oldRow的项目数组和调用方法后的数组不匹配。这背后的原因可能是什么?

没有 a good, minimal, complete code example,就无法确定您的场景中的问题所在。这里的上下文不够。

但很可能,您只是 运行 遇到了时间问题。也就是说,由 BeginInvoke() 调用的委托是异步执行的,稍后会在某个不确定的时间执行。由于它已排队等待执行,因此几乎肯定会在行更新发生后执行,因此您会在执行方法时看到新值。

可能的解决方案包括:

  1. 使用 Invoke() 方法代替 BeginInvoke()。这是同步执行的,确保在调用 OnRowEdit() 方法时未修改行对象。
  2. 如果您只需要行中的值,请在调用 BeginInvoke() 之前将这些值提取到临时对象(例如新数组)中,然后传递 that 对象行对象本身。
  3. 直接调用OnRowEdit()即可。缺少完整的代码示例,根本不清楚为什么要使用 BeginInvoke();通常,用户编辑操作发生在调度程序线程中,因此可以直接访问 UI 对象,而无需调用 Invoke()BeginInvoke()。请注意,这实际上与 #1 相同的选项……使用 Invoke() 可能只是多余的。

如果上述选项中的 none 适合您,请通过包含一个好的代码示例来改进问题,解释您为什么首先使用 BeginInvoke(),以及为什么 none 这些建议适用于您的情况。

Peter Duniho 所说的内容回答了您的确切问题。但在我看来,"correct" 这样做的方法是使用 ViewModel。然后您将拥有 "old" 的副本并可以验证 "new" 这将解决您的问题(我认为?)。您可以更全面地控制所发生的事情,并且 MVVM 也有许多其他好处。