简体   繁体   English

在C#中使用弱处理程序引发PropertyChanged事件时,发生ExecutionEngineException

[英]ExecutionEngineException occurs while raising PropertyChanged event with weak handlers in C#

I'm trying to raise a PropertyChanged event that is being listened to by a weak event handler (via PropertyChangedEventManager ). 我试图引发一个正在由弱事件处理程序(通过PropertyChangedEventManager )监听的PropertyChanged事件。 For some reason I'm getting an ExecutionEngineException when I raise the event. 出于某种原因,引发事件时会出现ExecutionEngineException

My event raising code looks like: 我的事件引发代码如下:

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

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

    return;
}

My handling code looks like: 我的处理代码如下:

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

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

    return lHandled;
}

I'm not getting any useful results when I search for this exception, and the exception itself doesn't contain any useful information! 搜索此异常时,没有得到任何有用的结果,并且异常本身不包含任何有用的信息! What's causing the problem? 是什么原因引起的?

Props to the author of the ExecutionEngineException when raising the PropertyChanged event blog entry. 引发PropertyChanged事件博客条目 ,向ExecutionEngineException的作者提出建议 He describes the problem and solution perfectly, but for some reason his page doesn't appear very high in web search results. 他完美地描述了问题和解决方案,但是由于某种原因,他的页面在网络搜索结果中的排名并不很高。 I wanted to post the question and answer here to help out more people who encounter the same issue. 我想在此处发布问题和答案,以帮助更多遇到相同问题的人。

So it turns out that WeakEventManager will call Environment.FailFast() if you return false from ReceiveWeakEvent . 因此,如果从ReceiveWeakEvent返回false ,则WeakEventManager将调用Environment.FailFast()

What an insidious bug! 真是个阴险的臭虫! I agree with a quote from the blog entry: 我同意博客条目中的引用:

This may be the most ridiculously over-reactive error processing I've ever seen in my life. 这可能是我一生中见过的最荒谬的过度反应错误处理。

My fixed handler looks like: 我的固定处理程序如下所示:

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;
}

The link in the accepted answer is no longer available (domain has lapsed), but the information is still available through the Wayback Machine. 接受的答案中的链接不再可用(域已失效),但是该信息仍然可以通过Wayback Machine获得。 I'm going to repeat the entire post here, with credit to the original author. 我将在此重复整个帖子,并感谢原始作者。 If that's not the right thing to do I'm sure someone will be along to correct it... 如果那不是正确的选择,我相信有人会纠正它。

ExecutionEngineException when raising the PropertyChanged event 引发PropertyChanged事件时发生ExecutionEngineException

Posted on April 23, 2009 by ceiled, on (their?) "Occam Says" blog. 由ceiled于2009年4月23日在(他们的?)“ Occam Says”博客上发布。

If you've ever seen an ExecutionEngineException in .NET, you know that it's nasty. 如果您曾经在.NET中看到过ExecutionEngineException,则知道它很讨厌。 It even sounds intimidating. 它甚至听起来令人生畏。 It's the error that's thrown by Environment.FailFast() — MSDN describes it as "the exception that is thrown when there is an internal error in the execution engine of the common language runtime." 这是Environment.FailFast()引发的错误-MSDN将其描述为“当公共语言运行时的执行引擎中出现内部错误时引发的异常”。 Before last night, the only time I'd ever seen it was when I was generating and running my own IL assembly code and I did something wrong like pop too many values off the stack or something. 在昨晚之前,我唯一见过的就是我生成并运行自己的IL汇编代码时,我做错了什么,例如从堆栈中弹出过多的值之类的东西。

However, last night I got it while raising a PropertyChanged event on my INotifyPropertyChanged object, immediately after using PropertyChangedEventManager to subscribe to it. 但是,昨晚在使用PropertyChangedEventManager对其进行订阅之后,立即在INotifyPropertyChanged对象上引发PropertyChanged事件时得到了它。 I scratched my head…how the hell did I manage to cause an internal error in the CLR? 我ed了挠头……我到底怎么导致CLR内部错误? I restarted Visual Studio, I rebooted my machine, I tried it on other machines to see if it was some sort of crazy corruption on my system, but it was completely repeatable. 我重新启动了Visual Studio,重新启动了我的机器,在其他机器上尝试了一下,看看这是否是我系统上的某种疯狂破坏,但它是完全可重复的。

Finally, in desperation, I set up .NET source stepping (something I've been meaning to do for a while anyway) and ran it again — this time, instead of showing up on the line where I raised the PropertyChanged event, the exception stopped on this code in WeakEventManager.cs: 最后,无奈之下,我设置了.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 }));
}

That's right…when ReceiveWeakEvent returns false (indicating that the listener did not handle the event being raised), WeakEventManager calls Environment.FailFast(). 没错,当ReceiveWeakEvent返回false(指示侦听器未处理正在引发的事件)时,WeakEventManager会调用Environment.FailFast()。 This is the software equivalent of people in horror movies choosing to shoot themselves in the face rather than turn into a zombie and possibly hurt their friends. 这相当于恐怖电影中的人选择在脸上拍摄自己而不是变成僵尸并可能伤害他们的朋友的软件。 It writes an event to the Event Viewer that says "Unrecoverable system error." 它将一个事件写入事件查看器,显示“无法恢复的系统错误”。

This may be the most ridiculously over-reactive error processing I've ever seen in my life, and for some reason, Google is completely unhelpful on this subject. 这可能是我一生中见过的最荒谬的,反应过度的错误处理,由于某种原因,Google对此完全没有帮助。 Searching for "PropertyChangedEventManager ExecutionEngineException" turns up virtually nothing — the only result in English was a 404, and Google's cached version didn't have either keyword in it, for some reason. 搜索“ PropertyChangedEventManager ExecutionEngineException”几乎没有任何结果-英文的唯一结果是404,并且由于某种原因,Google的缓存版本中没有两个关键字。 Hopefully this will save someone the intense frustration I experienced when I accidentally returned false from a random event handler somewhere, and was told that my execution engine had become unrecoverably corrupt and would be shut down for its own protection. 希望这可以节省我从某个地方的随机事件处理程序中意外返回false时遇到的强烈挫败感,并被告知我的执行引擎已变得不可恢复地损坏,并且将出于自身保护而关闭。 If this post helps you, please tell me so in the comments so I'll know my time wasn't completely wasted. 如果这篇文章对您有帮助,请在评论中告诉我,这样我就不会浪费我的时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM