检查对象中存在的特定事件是否存在事件处理程序

时间:2013-08-07 19:42:03

标签: c# events

我在for循环中使用了以下代码片段

DataTable childTable = dataTable.DataSet.Relations[relationName].ChildTable;

if (childTable != null)
{
   iBindingList = childTable.AsDataView() as IBindingList;
   iBindingList.ListChanged += new ListChangedEventHandler(GridDataRecord_ListChanged);
}

在这种情况下,我需要检查已经为iBindinglist对象调用了listchanged事件。您可以查看此内容并提供实现此目的的建议。谢谢Advcance。

此致 Rajasekar

2 个答案:

答案 0 :(得分:4)

无法查看您的处理程序是否已添加。幸运的是,你不需要。

iBindingList.ListChanged -= GridDataRecord_ListChanged;
iBindingList.ListChanged += GridDataRecord_ListChanged;

假设一个表现良好的类(在这种情况下,您应该能够相信该类表现良好),即使尚未添加GridDataRecord_ListChanged,也可以安全地删除它。删除它将无济于事。如果你只是在删除它之后添加处理程序,它将永远不会被添加多次。

答案 1 :(得分:1)

您可以在附加处理程序之前删除处理程序

if (childTable != null)
{
   iBindingList = childTable.AsDataView() as IBindingList;
   iBindingList.ListChanged -= new ListChangedEventHandler(GridDataRecord_ListChanged);
   iBindingList.ListChanged += new ListChangedEventHandler(GridDataRecord_ListChanged);
}

如果您正在运行单个线程环境,并且您始终如此附加此事件,则应该没问题。但是,如果有多个线程,则可能存在竞争条件。如评论中所述,如果您有多个线程附加同一个委托,则这是一个问题。 -=仅删除最后一个委托,因此多次添加和一次删除意味着事件仍然附加。

或者,使用一个标志来检查事件是否已订阅。

bool listChangedSubscribed = false;  
if (childTable != null)
{
   iBindingList = childTable.AsDataView() as IBindingList;
   iBindingList.ListChanged -= new ListChangedEventHandler(GridDataRecord_ListChanged);
   if(!listChangedSubscribed)
   {
       iBindingList.ListChanged += new ListChangedEventHandler(GridDataRecord_ListChanged);
       listChangedSubscribed = true; 
   }