我在我的 C# 代码中使用了一个特定的命令,效果很好。但是,据说它在“非托管”代码中行为不端。
什么是托管或非托管代码?
这是一篇关于这个主题的好文章。
总结一下,
在安装在同一台机器上的运行时引擎中执行的应用程序。没有它,应用程序将无法运行。运行时环境提供程序使用的通用软件例程库,并且通常执行内存管理。它还可以提供从源代码到可执行代码或从中间语言到可执行代码的即时 (JIT) 转换。Java、Visual Basic 和 .NET 的公共语言运行时 (CLR) 是运行时引擎的示例。(阅读更多)
自行运行的可执行程序。该程序从操作系统启动,调用和使用操作系统中的软件例程,但不需要使用另一个软件系统。已汇编成机器语言的汇编语言程序和针对特定平台编译成机器语言的 C/C++ 程序是非托管代码的示例。(阅读更多)
一些库代码需要调用非托管代码(例如,本机代码 API,如 Win32)。因为这意味着要超出托管代码的安全边界,所以需要格外小心。
以下是有关托管代码的其他一些补充说明:
对于您的问题:
我认为这是因为 NUnit 为 UnitTesting 执行您的代码,并且可能有一部分是非托管的。但我不确定,所以不要把它当作黄金。我相信有人可以给你更多关于它的信息。希望能帮助到你!
当您想到unmanaged时,请考虑特定于机器的机器级代码。就像 x86 汇编语言一样。非托管(本机)代码被编译和链接以直接在其设计的处理器上运行,目前不包括所有操作系统内容。它不是便携式的,但速度很快。非常简单,精简的代码。
托管代码是从 Java 到旧的 Interpretive BASIC 的所有内容,或者在 .NET 下运行的任何内容。托管代码通常被编译为中间级别的 P 代码或字节代码指令集。这些不是特定于机器的指令,尽管它们看起来类似于汇编语言。托管代码将程序与运行它的机器隔离开来,并创建一个安全边界,其中所有内存都是间接分配的,一般来说,您无法直接访问机器资源,如端口、内存地址空间、堆栈等. 这个想法是在更安全的环境中运行。
例如,要将托管变量转换为非托管变量,您必须获得实际对象本身。它可能被包裹或装在一些额外的包装中。非托管变量(比如'int')——在 32 位机器上——正好占用 4 个字节。没有开销或额外的包装。从托管代码到非托管代码——然后再返回——的过程称为“编组”。它允许您的程序跨越边界。
用尽可能少的词:
托管代码是 C#.Net、VB.Net、F#.Net 等编译器创建的。它在 CLR 上运行,其中包括提供垃圾收集、引用检查等服务。所以可以把它想象成,我的代码是由 CLR 管理的。
另一方面,非托管代码直接编译为机器代码。它不由 CLR 管理。
基本上非托管代码是不在 .NET CLR 下运行的代码(也不是 VB.NET、C# 等)。我的猜测是 NUnit 有一个不是 .NET 代码(又名 C++)的运行器/包装器。
托管代码:
根据与公共语言运行时的“合作合同”运行的代码。托管代码必须提供运行时所需的元数据,以提供诸如内存管理、跨语言集成、代码访问安全性和对象的自动生命周期控制等服务。所有基于 Microsoft 中间语言 (MSIL) 的代码都作为托管代码执行。非托管代码:
在不考虑公共语言运行时的约定和要求的情况下创建的代码。非托管代码在公共语言运行时环境中以最少的服务执行(例如,没有垃圾收集、有限的调试等)。
参考: http: //www.dotnetspider.com/forum/11612-difference-between-managed-and-unmanaged-code.aspx
NUnit 在单独的 AppDomain 中加载单元测试,我假设入口点没有被调用(可能不需要),因此入口程序集为空。
托管代码在 CLR 环境中运行,即 .NET 运行时。简而言之,所有 IL 都是托管代码。但是如果您使用一些第三方软件示例 VB6 或 VC++ 组件,它们是非托管代码,因为 .NET 运行时 (CLR) 没有控制权在语言的源代码执行上。
托管代码:- MSIL(中间语言)形式的代码是在语言编译器编译后开发的,并由CLR
调用的托管代码直接执行。例如:- .net 框架支持的所有 61 种语言代码
非托管代码:- 之前开发.net
的 MSIL 表单不可用且CLR
直接执行的CLR
代码将重定向到操作系统,这称为非托管代码。
eg:-COM,Win32 APIs
首先要明白这一点,之前.NET framework
,Microsoft
都是提供单机产品之类的MFC (Visual C++), VB, FoxPro
。
2002年,微软结合其产品,制作了.NET框架。现在,之前代码的执行方式与 .NET 框架中代码的管理和执行方式之间存在差异。Microsoft 引入了CLR
with .NET 框架的概念,它编译来自任何受支持的 .NET 框架语言的代码,并提供诸如此类的附加功能memory mangement, garbage collection
。但是,此类 CLR 功能以前无法直接使用。
因此,如果您在 .NET 框架(使用 CLR 编译)中创建库/代码,则称为
Managed code
. 您可以在其他 .NET 应用程序/项目中进一步使用此库,CLR 也将了解它之前的编译方式,这就是为什么它仍然是您的管理代码的原因。
OTOH,如果您想使用在 .NET 框架之前编写的库,那么您可以做一些限制,但请记住,由于当时 CLR 不存在,所以现在,CLR 不会再次理解和编译此代码. 这将被称为unmanaged code
. 请注意,某些第三方为提供某些功能/工具而创建的库/程序集如果不兼容 CLR,也可能被视为非管理代码。
用外行的话来说,管理代码是您的 CLR 可以理解并可以自行编译以供进一步执行的东西。在 .NET 框架中,(来自在 .NET 框架上工作的任何语言)当代码转到 CLR 时,代码会提供一些元数据信息,以便 CLR 可以为您提供此处指定的功能。他们很少是Garbage collection, Performance improvements, cross-language integration, memory management
等等。
OTOH,未管理的代码是特定于机器并且可以使用的东西,无需进一步处理。
从 Pro C# 5 和 .NET 4.5 框架:
托管代码与非托管代码: 了解 C# 语言的最重要一点可能是它可以生成只能在 .NET 运行时执行的代码(您永远不能使用 C# 构建本机 COM 服务器或非托管 C/C++应用)。正式来说,用于描述面向 .NET 运行时的代码的术语是托管代码。包含托管代码的二进制单元称为程序集(稍后会详细介绍程序集)。相反,不能由 .NET 运行时直接托管的代码称为非托管代码。