【问题标题】:event is not null but _invocationList is null?事件不为空但 _invocationList 为空?
【发布时间】:2010-12-20 19:51:23
【问题描述】:

我想如果我有这个代码:

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null) PropertyChanged(this, e);
    }

并且PropertyChanged 事件没有被钩住,ProeprtyChanged 将是null,但我得到一个不为空的PropertyChanged,其_invocationList 成员是null,其@987654328 @ member 为 0。当我调用 PropertyChanged(this, e) 时,这(我认为)会导致 ArgumentOutOfRangeException。知道问题出在哪里吗?

这是我在 OnClick 事件中的堆栈跟踪:

在 System.Collections.ArrayList.get_Item(Int32 索引) 在 System.Windows.Forms.BindingsCollection.get_Item(Int32 索引) 在 System.Windows.Forms.BindingManagerBase.PushData(布尔值&成功) 在 System.Windows.Forms.PropertyManager.OnCurrentChanged(EventArgs ea) 在 System.Windows.Forms.BindToObject.PropValueChanged(对象发送者,EventArgs e) 在 System.EventHandler.Invoke(对象发送者,EventArgs e) 在 System.ComponentModel.PropertyDescriptor.OnValueChanged(对象组件,EventArgs e) 在 System.ComponentModel.ReflectPropertyDescriptor.OnValueChanged(对象组件,EventArgs e) 在 System.ComponentModel.ReflectPropertyDescriptor.OnINotifyPropertyChanged(对象组件,PropertyChangedEventArgs e) 在 Player.DataBaseManager.OnPropertyChanged(PropertyChangedEventArgs e) 在 C:\Users\Juan Luis\My Dropbox\Documents\CodeWebScraper sin Player\WebScraperAndPlayer\Player\DataBaseManager2.cs:line 100 在 C:\Users\Juan Luis\My Dropbox\Documents\CodeWebScraper sin Player\WebScraperAndPlayer\Player\DataBaseManager2.cs:line 30 中的 Player.DataBaseManager.set_TableNames(List`1 value) 在 Player.DataBaseManager.UpdateTableNames() 在 C:\Users\Juan Luis\My Dropbox\Documents\CodeWebScraper sin Player\WebScraperAndPlayer\Player\DataBaseManager2.cs:line 95 在 C:\Users\Juan Luis\My Dropbox\Documents\CodeWebScraper sin Player\WebScraperAndPlayer\Player\DataBaseManager2.cs:line 336 中的 Player.DataBaseManager.ExecuteNonQuery(String sqlQuery) 在 C:\Users\Juan Luis\My Dropbox\Documents\CodeWebScraper sin Player\WebScraperAndPlayer\BuilderForm2\Data\DataBaseEditor.cs:line 90 中的 WebScraperAndPlayer.DataBaseEditor.deleteTableButton_Click(Object sender, EventArgs e) 在 System.Windows.Forms.ToolStripItem.RaiseEvent(对象键,EventArgs e) 在 System.Windows.Forms.ToolStripButton.OnClick(EventArgs e)

【问题讨论】:

  • 异常出现在调试器的什么地方?
  • PropertyChanged(this, e)

标签: c# .net winforms events


【解决方案1】:

查看您的堆栈跟踪

在 System.Windows.Forms.BindingsCollection.get_Item(Int32 index) 在 System.Collections.ArrayList.get_Item(Int32 index) 在 System.Windows.Forms.BindingManagerBase.PushData(Boolean&success) 在

这不是事件连接的问题,您的数据绑定中有其他问题。

【讨论】:

  • 我看到了,但是获取一个不为空且其调用列表为空的事件仍然不是问题吗?
  • @jsoldi 为什么你如此专注于调用列表?就我而言,这是我不在乎的幕后管道。检查您的事件代码,特别是在您使用 ArrayList 的任何地方。
  • @jsoldi:不,不是。 @Mike Caron 指出了你不应该关心的原因。我不知道_invocationList 是什么,但我知道null 不一定有问题。
  • 好的,好的。我会尝试做更深入的调试。
【解决方案2】:

System.EventHandler.Invoke(Object sender, EventArgs e)

那是 PropertyChanged(this, e) 调用。这不是异常的原因,您的堆栈跟踪远远超出了此范围。不幸的是,在您没有编写的代码中,它是 Winforms 绑定管道的一部分。装订出了点问题。

【讨论】:

    【解决方案3】:

    发现问题。我有一个数据表编辑器,它有一个TablesList 属性绑定到数据库管理器对象中的数据表列表。在其set 访问器中,我检查了该表是否仍然存在于列表中,如果它没有,编辑器关闭并从数据库管理器中删除了数据绑定。因此,当 .NET 的内部循环遍历绑定到 TablesList 的对象时,其中一个将自己从列表中删除。但是 .NET 并没有注意到这种变化,因为循环的编写方式:

    int numLinks = Bindings.Count;
    for (int i = 0; i < numLinks; i++) { 
        if (Bindings[i].PushData()) { 
            success = false;
        } 
    }
    

    我基本上是从PushData() 调用中删除绑定。我的解决方案是将事件处理程序附加到PropertyChanged 事件并检查那里的表格列表。显然,无论 .NET 使用什么循环来遍历事件的调用列表,您都可以在循环中删除一个事件。

    我想道德是:永远不要删除从该属性的set 访问器更新属性的Binding;但是可以从事件处理程序本身中删除事件处理程序。对吧?

    【讨论】:

      猜你喜欢
      • 2020-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多