2

I'm trying to raise a PropertyChanged event that is being listened to by a weak event handler (via PropertyChangedEventManager). For some reason I'm getting an ExecutionEngineException when I raise the event.

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?

sourcenouveau
  • 29,356
  • 35
  • 146
  • 243

2 Answers2

6

Props to the author of the ExecutionEngineException when raising the PropertyChanged event blog entry. 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.

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;
}
sourcenouveau
  • 29,356
  • 35
  • 146
  • 243
  • 1
    Hehe. Kind of classic, this is actually triggered by an Assert(). The programmer surely didn't realize that this particular method would still assert in the release build. You can get a better outcome by setting the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\DbgJITDebugLaunchSetting setting to 0x12. – Hans Passant Mar 15 '12 at 20:46
  • So glad you posted this; I never would've thought that returning false from the event handler would result in a FailFast, but apparently it does. – Dan Bryant Nov 06 '13 at 14:18
  • The link in the first paragraph is no longer available. I've repeated the content in a separate answer. – njplumridge Dec 14 '15 at 15:31
1

The link in the accepted answer is no longer available (domain has lapsed), but the information is still available through the 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

Posted on April 23, 2009 by ceiled, on (their?) "Occam Says" blog.

If you’ve ever seen an ExecutionEngineException in .NET, you know that it’s nasty. 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." 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.

However, last night I got it while raising a PropertyChanged event on my INotifyPropertyChanged object, immediately after using PropertyChangedEventManager to subscribe to it. I scratched my head…how the hell did I manage to cause an internal error in the 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.

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:


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(). 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. 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. 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. If this post helps you, please tell me so in the comments so I’ll know my time wasn’t completely wasted.

Community
  • 1
  • 1
njplumridge
  • 336
  • 3
  • 11