2

我试图提出弱事件处理程序(通过PropertyChangedEventManager)正在侦听的PropertyChanged事件。出于某种原因,我在举办活动时得到了ExecutionEngineExceptionExecutionEngineException发生在C#中的弱处理程序引发PropertyChanged事件

我的事件提高代码如下所示:

protected virtual void RaisePropertyChanged(string aPropertyName) 
{ 
    var lHandler = this.PropertyChanged; 

    if (lHandler != null) 
    { 
     // ExecutionEngineException is thrown here 
     lHandler(this, new PropertyChangedEventArgs(aPropertyName)); 
    } 

    return; 
} 

我处理的代码如下所示:

public bool ReceiveWeakEvent(Type aManagerType, object aSender, EventArgs e) 
{ 
    bool lHandled = false; 

    if (aManagerType == typeof(PropertyChangedEventManager)) 
    { 
     OnPropertyChanged(aSender, e as PropertyChangedEventArgs); 
    } 

    return lHandled; 
} 

我没有得到任何有用的结果,当我搜索此异常,异常本身不包含任何有用的信息!是什么导致了这个问题?

回答

5

支付作者ExecutionEngineException when raising the PropertyChanged event博客条目。他完美地描述了问题和解决方案,但由于某种原因,他的网页在网络搜索结果中并不显得很高。我想在这里发布问题和答案,以帮助更多遇到同样问题的人。

所以事实证明,WeakEventManager将拨打Environment.FailFast()如果你从ReceiveWeakEvent返回false

什么是一个阴险的bug!我同意从博客条目的引用:

这可能是我见过的生活中最可笑的过度反应性错误处理。

我固定的处理程序是这样的:

public bool ReceiveWeakEvent(Type aManagerType, object aSender, EventArgs e) 
{ 
    bool lHandled = false; 

    if (aManagerType == typeof(PropertyChangedEventManager)) 
    { 
     OnPropertyChanged(aSender, e as PropertyChangedEventArgs); 
     lHandled = true; 
    } 

    return lHandled; 
} 
+1

呵呵。经典的,这实际上是由一个Assert()触发的。程序员当然没有意识到这个特定的方法仍然会在发布版本中声明。通过将HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ .NETFramework \ DbgJITDebugLaunchSetting设置设置为0x12,可以获得更好的结果。 – 2012-03-15 20:46:12

+0

很高兴你发布了这个;我从来不会认为从事件处理程序返回false会导致FailFast,但显然它会。 – 2013-11-06 14:18:50

+0

第一段中的链接不再可用。我在一个单独的答案中重复了这些内容。 – njplumridge 2015-12-14 15:31:40

1

在接受答案的链接不再可用(域名已失效),但信息仍然可以通过Wayback机器。我将在这里重复整篇文章,并赞扬原作者。如果这不是正确的事情由ceiled提高对2009年4月23日,PropertyChanged事件

发布时做我敢肯定有人会沿着纠正它...

ExecutionEngineException,在(他们的? )“奥卡姆说”博客。

如果你曾经在.NET中看到ExecutionEngineException,你就知道它很讨厌。它甚至听起来很吓人。这是Environment.FailFast()引发的错误 - MSDN将其描述为“在公共语言运行库的执行引擎中存在内部错误时引发的异常。”在昨天晚上之前,我唯一见过它的时候是在生成和运行我自己的IL汇编代码时,我做了一些错误,比如弹出堆栈中的太多值或其他东西。

但是,昨晚我在使用PropertyChangedEventManager订阅它时立即在我的INotifyPropertyChanged对象上引发了一个PropertyChanged事件。我抓住了我的头......我怎么会在CLR中造成内部错误?我重新启动了Visual Studio,重新启动了机器,在其他机器上尝试了它,看看它是否是我的系统上的某种疯狂的腐败,但它是完全可重复的。

最后,无奈之下,我成立了。NET源程序步骤(我一直想要做一段时间),然后再次运行它 - 这次,我没有在引发PropertyChanged事件的行上显示,而是在WeakEventManager.cs中的此代码中停止了异常:


bool condition = listener.ReceiveWeakEvent(managerType, sender, args); 
if (!condition) 
{ 
    Invariant.Assert(condition, SR.Get("ListenerDidNotHandleEvent"), SR.Get("ListenerDidNotHandleEventDetail", new object[] { listener.GetType(), managerType })); 
} 

这是正确的...当ReceiveWeakEvent返回false(表明听者不处理被引发的事件),调用WeakEventManager的Environment.FailFast()。这是相当于恐怖电影中的人选择在脸上自拍而不是变成僵尸并可能伤害他们的朋友的软件。它将事件写入事件查看器,并显示“不可恢复的系统错误”。

这可能是我在生活中见过的最可笑的过度反应性错误处理,由于某种原因,Google对这个问题完全没有帮助。搜索“PropertyChangedEventManager ExecutionEngineException”实际上没有任何结果 - 英文中的唯一结果是404,而且由于某种原因,Google的缓存版本中没有任何关键字。希望这可以帮助我们避免某些人在我偶然从某个随机事件处理程序返回错误时遇到的强烈挫折,并被告知我的执行引擎已经变得无法恢复,并且会因为自身的保护而被关闭。如果这篇文章可以帮助你,请在评论中告诉我,所以我会知道我的时间并没有完全被浪费。

相关问题