为什么不应在订阅同一组件的事件处理程序中对.NET组件进行方法调用?

时间:2014-02-26 12:39:13

标签: c# winforms events

我正在调查一个音频组件 - 用于.NET的AudioSoundRecorder - 并在one of their documentation pages上,他们声明:

  

对于某个.NET组件的方法的调用永远不应该从同一.NET组件生成的事件的管理函数中执行:这通常是导致错误和死锁情况的原因,并且它会导致错误。应该始终避免的做法......

我之前从未听说过.NET的这种限制。任何人都可以向我解释为什么要始终避免这种情况,除了错误和死锁情况之外'提到?肯定处理死锁应该是组件的责任吗?

2 个答案:

答案 0 :(得分:0)

  

当然处理死锁应该是组件的责任吗?

理论上,对于表现良好的组件,是的。但有些组成部分可能不这样做 而且,由于这是组件内部结构的一部分,因此它可能会在不同版本之间发生变化。如果版本1无意中阻止了死锁,但在架构更改后v2不再阻止它们。在这种情况下,更新依赖项可能会破坏您的代码。

因此,最好不要在处理程序中为组件的某个事件调用组件方法,或者,如果必须这样做,则自己处理死锁。

答案 1 :(得分:0)

在不知道AudioSoundRecorder的细节的情况下,我认为它们意味着什么是这样的:

Event是一个简单的异步方法调用。如果一个组件在外部(到组件)代码中调用一个方法引发了一个事件,并且该外部代码回调到组件中,那么你会遇到这样的情况:

  1. 组件正在做一些尚未完成的事情
  2. 该组件通过事件调用外部代码
  3. 外部代码回调组件以执行其他操作
  4. 此时,您可能因为组件尚未实际完成步骤1,无论在步骤3中要求做什么可能适合也可能不适合。例如,步骤1是加载大型声音文件,步骤2中的事件是说“我是通过加载的x%”,并且对组件的请求是分析声音文件,即分析请求由于文件未完全加载,可能会失败。

    请注意,当事件代码正在运行时,组件代码不是:事件调用通常是异步的,因此在事件调用返回之前(当调用方法完成时)组件可能无法执行任何处理。您在被调用方法中执行的操作越多,组件在步骤1中完成原始调用的速度就越慢。

    另请注意,在我上面详述的示例中,如果步骤3在加载百分比为100时调用Analyze,则原始Load调用仍未返回:在处理事件并且控制返回之前,它不会实际返回到组件,然后它可以完成并重新调用调用代码(无论调用步骤1)。

    这有帮助吗?