注释
本文特定于 .NET Framework。 它不适用于 .NET 的较新版本实现,包括 .NET 6 及更高版本。
卷影复制使应用程序域中使用的程序集可以更新,而无需卸载应用程序域。 这对于必须持续可用的应用程序特别有用,例如 ASP.NET 站点。
重要
在 Windows 8.x 应用商店应用中,卷影复制功能不被支持。
公共语言运行时在加载程序集时锁定程序集文件,因此在卸载程序集之前无法更新该文件。 从应用程序域中卸载程序集的唯一方法是卸载应用程序域,因此在正常情况下,在卸载使用该程序集的所有应用程序域之前,不能在磁盘上更新程序集。
将应用程序域配置为卷影复制文件时,应用程序路径中的程序集将复制到另一个位置并从该位置加载。 副本已锁定,但原始程序集文件已解锁,可以更新。
重要
唯一可以卷影复制的程序集是存储在应用程序目录或其子目录中的,而这些目录在配置应用程序域时由ApplicationBase和PrivateBinPath属性指定。 存储在全局程序集缓存中的程序集不进行影子复制。
本文包含以下各节:
启用和使用卷影复制 描述了基本用途以及可用于卷影复制的选项。
启动性能 描述了在 .NET Framework 4 中对卷影复制所做的更改,以提高启动性能,以及如何还原到早期版本的行为。
过时的方法 描述了对控制 .NET Framework 2.0 中卷影复制的属性和方法所做的更改。
启用和使用卷影复制
使用 AppDomainSetup 类的属性来配置应用程序域以进行卷影复制,如下所示:
通过设置属性 ShadowCopyFiles 为字符串值
"true"
来启用影子复制。默认情况下,此设置会导致应用程序路径中的所有程序集在加载之前复制到下载缓存。 这是公共语言运行时维护的同一缓存,用于存储从其他计算机下载的文件,公共语言运行时在不再需要文件时会自动删除这些文件。
(可选)使用 CachePath 属性和 ApplicationName 属性设置卷影复制文件的自定义位置。
该位置的基路径通过将 ApplicationName 属性串联为 CachePath 子目录来构成。 将程序集卷影复制到此路径的子目录,而不是复制到基路径本身。
注释
如果未设置该 ApplicationName 属性,则会忽略该 CachePath 属性,并使用下载缓存。 不会引发异常。
如果你指定了自定义的位置,那么在不再需要时,你有责任清理这些目录及其复制的文件。 它们不会自动删除。
为卷影复制文件设置自定义位置还存在以下几个原因。 如果应用程序生成大量副本,则可能需要为卷影复制的文件设置自定义位置。 下载缓存受大小限制,而不是按生存期限制,因此公共语言运行时可能会尝试删除仍在使用的文件。 设置自定义位置的另一个原因是运行应用程序的用户对公共语言运行时用于下载缓存的目录位置没有写入访问权限。
或者,使用 ShadowCopyDirectories 属性限制卷影复制的程序集。
启用应用程序域的卷影复制时,默认设置是复制应用程序路径中的所有程序集,即由ApplicationBase和PrivateBinPath属性指定的目录。 可以通过创建仅包含要影子复制的目录的字符串并将字符串分配给 ShadowCopyDirectories 属性来限制复制到所选目录。 用分号分隔目录。 只有选定目录中的程序集才进行卷影复制。
注释
如果未向 ShadowCopyDirectories 属性分配字符串,或者将此属性设置为
null
,则由 ApplicationBase 和 PrivateBinPath 属性指定的目录中的所有程序集都将被影子复制。重要
目录路径不得包含分号,因为分号是分隔符字符。 分号没有转义符。
启动性能
当使用卷影复制的应用程序域启动时,应用程序目录中的程序集复制到卷影复制目录时存在延迟,或者验证它们是否已位于该位置。 在 .NET Framework 4 之前,所有程序集都复制到临时目录。 已打开每个程序集以验证程序集名称,并验证了强名称。 已检查每个程序集以查看其更新到的版本是否比卷影复制目录中的副本新。 如果是,则将它复制到卷影复制目录。 最后,删除临时副本。
从 .NET Framework 4 开始,默认启动行为是将应用程序目录中每个程序集的文件日期和时间与卷影复制目录中复制的文件日期和时间进行比较。 如果程序集已更新,则使用与 .NET Framework 早期版本中相同的过程复制该程序集;否则,将加载卷影复制目录中的副本。
对于程序集不经常变化且变化通常发生在少部分程序集中的应用程序,生成的性能改进效果最大。 如果应用程序中的大多数程序集频繁变化,新的默认行为可能会导致性能下降。 可以通过将 <shadowCopyVerifyByTimestamp> 元素 添加到配置文件,以恢复 .NET Framework 早期版本的启动行为enabled="false"
。
已过时的方法
此类AppDomain具有多种方法,例如SetShadowCopyFiles和ClearShadowCopyPath,可用于控制应用程序域上的卷影复制,但这些方法已在 .NET Framework 版本 2.0 中被标记为过时。 为卷影复制配置应用程序域的建议方法是使用类的属性 AppDomainSetup 。