2

我正在尝试引发一个弱事件处理程序正在侦听的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;
}

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

4

2 回答 2

6

在引发 PropertyChanged 事件博客条目时向 ExecutionEngineException 的作者提供道具。他完美地描述了问题和解决方案,但由于某种原因,他的页面在网络搜索结果中的排名并不高。我想在这里发布问题和答案,以帮助更多遇到相同问题的人。

所以事实证明,如果您从ReceiveWeakEvent返回, WeakEventManager将调用Environment.FailFast()false

多么阴险的错误!我同意博客条目中的一句话:

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

我的固定处理程序看起来像:

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;
}
于 2012-03-15T20:13:31.060 回答
1

已接受答案中的链接不再可用(域已失效),但仍可通过 Wayback Machine 获得信息。我将在这里重复整个帖子,感谢原作者。如果这不是正确的做法,我相信有人会纠正它......

引发 PropertyChanged 事件时的 ExecutionEngineException

ceiled 于 2009 年 4 月 23 日在(他们的?)“奥卡姆说”博客上发表。

如果您曾经在 .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,而且由于某种原因,Google 的缓存版本中没有任何关键字。希望这能避免我在某个地方的随机事件处理程序不小心返回 false 时所经历的强烈挫败感,并被告知我的执行引擎已变得不可恢复地损坏并且将被关闭以进行保护。如果这篇文章对你有帮助,请在评论中告诉我,这样我就知道我的时间并没有完全浪费。

于 2015-12-14T15:17:12.117 回答