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

时间:2012-03-15 20:13:11

标签: c# inotifypropertychanged weak-references executionengineexception

我正在尝试引发由弱事件处理程序(通过PropertyChanged)监听的PropertyChangedEventManager事件。出于某种原因,当我举起活动时,我得到ExecutionEngineException

我的活动代码如下:

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

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

2 个答案:

答案 0 :(得分:5)

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

因此,如果您从WeakEventManager返回false,则Environment.FailFast()会调用ReceiveWeakEvent

多么阴险的错误!我同意博客文章的引用:

  

这可能是我一生中见过的最荒谬的过度反应错误处理。

我的固定处理程序如下:

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 :(得分:1)

已接受答案中的链接不再可用(域已失效),但仍可通过Wayback Machine获取该信息。我将在这里重复整篇文章,并对原作者表示赞赏。如果这不是正确的事情,我确定有人会纠正它......

引发PropertyChanged事件时

ExecutionEngineException

发表于2009年4月23日,由ceiled,on(他们的?)"奥卡姆说"博客。

如果您曾在.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()。这个软件相当于恐怖电影中的人选择在脸上拍摄自己而不是变成僵尸并可能伤害他们的朋友。它将事件写入事件查看器,该事件显示"不可恢复的系统错误。"

这可能是我生命中见过的最荒谬的过度反应错误处理,出于某种原因,谷歌在这个问题上完全没有帮助。正在搜索" PropertyChangedEventManager ExecutionEngineException"几乎没有任何结果 - 英语中唯一的结果是404,谷歌的缓存版本由于某些原因没有任何关键字。希望这可以拯救某些人,当我意外地从一个随机事件处理程序返回false时,我遇到了强烈的挫败感,并被告知我的执行引擎已经变得无法恢复腐败并且会被关闭以保护自己。如果这篇文章对你有帮助,请在评论中告诉我,以便我知道我的时间并没有完全浪费。