【问题标题】:Strange System.__Canon exception奇怪的系统.__佳能异常
【发布时间】:2013-05-31 09:44:23
【问题描述】:

我有一个使用单例类 ThreadQueue<T> 的 Windows 服务。当服务启动时,它会调用 ThreadQueue<string>.Start() 这个类,然后接受并将并发限制为可配置线程数的任务。

ThreadQueue<string>.Start() 只在服务启动时调用一次。

有时,在服务运行几个小时后,我会收到以下异常:

Application: myservice.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.NullReferenceException
Stack:
   at Apollo.Business.Framework.Threading.ThreadQueue.ThreadQueue`1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Start()
   at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Threading.ThreadHelper.ThreadStart()

System.__Canon 是什么?是什么让这个调用将 this 作为类型参数传入?

谁能解释一下?

【问题讨论】:

  • 你试过在Debug模式下编译吗?
  • 已经是了,你问这个干嘛?

标签: c# multithreading c#-4.0 singleton


【解决方案1】:

您应该读取方法参数类型名称中的任何内容。 System.__Canon 是与 CLR 中实现泛型的方式相关的实现细节。我不知道它的确切用法,但强烈怀疑它是由 Ngen.exe 使用的,Ngen.exe 是 .NET 中预装配程序集的优化工具。由于具体类型是在运行时实例化的,因此泛型在预抖动中是一个问题。您将获得采用类型参数的参数类型的方法的多个副本。仅处理 any 引用类型的 一个 方法,每个值类型的附加方法(如果有)。 System.__Canon 可以是任何引用类型的占位符的替代类型,即使 Ngen.exe 无法猜测在运行时将使用哪种实际类型,它也可以预置该方法。类似的东西。

鞋子很合适,Apollo.Business.Framework.Threading.ThreadQueue 听起来像是框架样式库中存在的那种类,当它被安装时会被预先设置,因为它应该被多个程序使用。

所以忽略类型名称,关注实际异常。 NullReferenceException 当然是一个非常常见的异常。堆栈跟踪中没有其他可见的东西可以提示导致它的原因。我猜想那个“阿波罗”框架的初始化问题,一些应该有一个值但仍然为空的对象。查看 ThreadQueue 构造函数的源代码应该会给出提示。如果没有,请致电供应商寻求帮助。一个 8 年老版本的 jitter 中的一个 bug 解释的不是很好,那些 bug 早就修复了。

【讨论】:

  • “仅处理 any 引用类型的 one 方法”-我认为 JIT 可以通过引用实例化泛型类型的多个实现-用于对实例成员进行非virtual 调用的类型?
【解决方案2】:

现在运行时和框架已经开源,回答这类问题要容易得多。 __Canon 的定义在here 可用。引用:

// Internal methodtable used to instantiate the "canonical" methodtable for generic instantiations.
// The name "__Canon" will never been seen by users but it will appear a lot in debugger stack traces
// involving generics so it is kept deliberately short as to avoid being a nuisance.

[Serializable]
[ClassInterface(ClassInterfaceType.AutoDual)]
[System.Runtime.InteropServices.ComVisible(true)]
internal class __Canon
{
}

正如评论所解释的,它是泛型的实现细节,是“规范”的缩写。

【讨论】:

  • 我完全不相信这条评论。我想有人认为__Canon 是一个很棒的 WTF 名字并使用了它。如果他们真的需要在调用堆栈中简短且具有描述性的内容,为什么他们不使用 __T__RefT 之类的东西?
猜你喜欢
  • 2011-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多