千里之行,始于足下

酌贪泉而觉爽,处涸辙而犹欢

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  34 随笔 :: 0 文章 :: 188 评论 :: 10 引用

关于ExecuteEngineException,在.net framework SDK中有这样的描述:

“执行引擎错误是致命错误,决不应该发生。此类错误主要是在执行引擎被破坏或丢失数据时发生的。系统会随时引发此异常。在可能的情况下,系统将引发比 ExecutionEngineException 异常能提供更多信息的异常。

应用程序不应引发 ExecutionEngineException。”

从这个描述可以看出,ExecutionEngineException这个异常在正常的程序中应当是不可能发生的,致命错误嘛。然而我今天却就与这个异常来了个多次碰头。

具体情况大致是这样的:一个具有查看器(Viewer)功能的COM控件,在.net中使用。这个Viewer有一个特性,在当前可视区域发生某些变化时,将会触发两个事件,而在更特定的情况下,这两个事件触发的时间差可能非常之小,几乎是同时发生。此时外层的.net程序引发ExecutionEngineException异常的可能性就变得非常之大,基本上每次操作都至少遇上一次,当然也只能遇上一次,因为一遇上就差不多Crash了。

应该还是在.net与COM交互时发生的问题,虽然不清楚具体过程,也可以大概猜想一下:当第一个事件发生的时候,.net开始对它进行处理,没等处理完毕,第二个事件又发生了,异常也就诞生了。

知道原因就好办。加入一个事件挂起机制,使得任意两个事件的触发时间间隔不会太小,避免两个事件几乎同时触发的情况再次发生。果然,一试之下再也没有出现这个异常了。如果有遇上类似现象的,不妨用这个思路试一下。

PS,这里我使用的环境是.net framework 1.1,目前尚不知在.net framework 2.0下是否有同样的现象。

posted on 2006-08-21 20:33 sunwaywei 阅读(1114) 评论(4)  编辑 收藏 网摘 所属分类: 开发心得

评论

#1楼 2006-08-22 09:50 sanni:mylove      
@sunwaywei

事件挂起你要怎样做?

  回复  引用  查看    

#2楼[楼主] 2006-08-22 11:04 sunwaywei      
@sanni:mylove
这个方法很多吧,我是用的最简单的,因为这里的事件对实时响应要求不是特别高,所以我规定如果本次事件与上次事件发生的时间间隔小于某个值,则将后一个事件挂起,过了间隔之后再次引发。

当然这个方法并不适用于所有情况,对我的应用来说,由于后一个事件都是一个状态变化的通知事件,迟些引发是没有什么问题的。如果在挂起过程中,这个事件再次被引发,则直接修改被挂起事件的相关参数,相应的可以降低通知事件的引发频率,减少一些无谓消耗。:)

  回复  引用  查看    

#3楼 2006-08-22 23:31 lixiong      
"


2.内存移动

如果在CLR中需要传递一块托管的buffer到非托管API,以便非托管API可以异步地向这个buffer填充数据。但是开发人员忘记用C#中的fixed关键字和或者MC++中的__pin关键字pin住这个object,那么GC发生的时候buffer就可能被GC移动导致地址发生改变。当非托管API试图写入旧地址的时候,好的情况就是发生crash,坏的情况就是不知道损坏了一块什么样的数据,最后崩溃到CLR的某个内部函数上,或者产生一个ExecutionEngineException。这种问题虽然是开发人员的错,但是调试起来非常头疼。因为问题不会立刻暴露出来,从callstack上也看不出任何线索,问题还不容易重现,每次出错的地方还不一样。这是由于CLR增加OS上的另一层内存管理机制,本意是减少开发人员的开销,但结果却使得开发人员要考虑更多的因素。同样类型的问题还会出现在COM object的使用上。如果COM指针在托管代码和非托管代码之间传递多次,由于某个非托管代码的错误,导致引用计数被多减了一次,使得指针在CLR不知情的情况下提前释放。最后CLR操作COM的时候CLR可能就会崩溃。解决这类问题单通过检查dump很难找出根源,一定要有一个重现环境,配合CLR的stresslog来调试。


"

  回复  引用  查看    

#4楼[楼主] 2006-08-23 07:29 sunwaywei      
@lixiong
谢谢你提供的信息。看来托管代码和非托管代码之间互操作仍然是有很多隐忧的。

我的程序基本上可以排除引用计数有误之类的情况,应当是CLR自身机制上存在缺陷吧。当时出错的时候,也是在检查事件的引发过程时根据直觉判断的。

  回复  引用  查看    




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 482674




相关文章:

相关链接: