Silverlight自定义类库实现应用程序缓存

简介: 默认情况下,如果SL项目引用了一些其它程序集(即通俗意义上的dll文件),在编译打包时,这些dll会全部打包到一个xap文件里,随着引用的dll文件越来越多,xap文件会越来越大。 这还不是最严重的问题,如果确实需要使用这些dll,大就大吧,要用它容量肯定就会增加。

默认情况下,如果SL项目引用了一些其它程序集(即通俗意义上的dll文件),在编译打包时,这些dll会全部打包到一个xap文件里,随着引用的dll文件越来越多,xap文件会越来越大。

这还不是最严重的问题,如果确实需要使用这些dll,大就大吧,要用它容量肯定就会增加。但是如果多个SL项目都要引用相同的程序集时,这些dll会重复打包进每个xap文件,用户在加载多个xap时,实际上是重复下载了这部分dll文件,带宽使用率太低。

为了改善这种情况,SL引用了"应用程序库缓存"的概念,在vs2010的SL项目中,打开SL项目的属性页,会看到一个选项:“通过使用应用程序库缓存减少XAP大小(R)”

img_90c303aa5a9d5a2b7d21937ef571ba41.png

勾上这个后,查看一下最终的ClientBin目录,会发现一些项目引用的其它程序集,已经分离出来变成了zip文件

img_f2ee7a3682faa9887525e659e6351546.png

再稍微唠叨一下:上图中的MySLApp.xap在下载时,怎么知道会去加载System.Runtime.Serialization.Json.zip呢?

揭密:随便找个解压软件(比如WinRAR,WinZIP,7-ZIP之类),用它打开MySLApp.xap文件,把里面的AppManifest.xaml解压出来,用记事本打开,会看到类似以下内容:

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="MySLApp" EntryPointType="MySLApp.App" RuntimeVersion="4.0.50826.0">
  <Deployment.Parts>
    <AssemblyPart x:Name="MySLApp" Source="MySLApp.dll" />
  </Deployment.Parts>
  <Deployment.ExternalParts>
    <ExtensionPart Source="System.Runtime.Serialization.Json.zip" />  
  </Deployment.ExternalParts>
</Deployment>

这里的 <ExtensionPart Source="System.Xml.Serialization.zip" />就通知运行时加载同目录下的System.Xml.Serialization.zip,首次加载时会下载所有xap以及相关的zip文件,以后再次浏览页面时,如果缓存没有清空掉,zip文件将直接从缓存中读取,不会重复下载。

但是有一个问题,只有强命名的程序集可以这么做,如果是用户自己开发的类库,默认情况下就算你勾选了这个选项,最终还是会将dll一起打包进xap文件,如何也让自己开发的SL类库使用缓存呢?

步骤1:先为自己的SL类库程序集(使用强名称)签名

这一步可以借助vs2010完成,见下图

img_11e3a224cdefe8552784bd662ddadb6a.png

然后重新编译

步骤2:创建xml映射文件

打开SL类库的编译输出目录(默认为bin\Debug目录),创建一个xml文件,文件名规则如下

比如类库输出的dll文件名为MyTools.dll,则这个xml文件必须是MyTools.extmap.xml,即 "dll文件主名+.extmap.xml"(且这个文件必须跟dll文件处于同一级目录),内容如下:

<?xml version="1.0"?>
<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <assembly>
    <name>MyTools</name>
    <version>1.0.0.0</version>
    <publickeytoken>c934ea1d360b6e15</publickeytoken>
    <relpath>MyTools.dll</relpath>
    <extension downloadUri="MyTools.zip" />
  </assembly>
</manifest>
解释一下:
name 为SL类库程序集的完整名称
version 指版本号(必须与AssemblyInfo.cs中的版本号一致)
publickeytoken 这个东东可以通过sn.exe工具查看(后面会讲到)
以上三项信息,必须与程序集的元数据一致
relpath 即为dll文件的物理文件名
downloadUri 这个一般把dll文件名扩展名改成.zip即可
publickeytoken的查看方法:
打开vs.net-->工具-->外部工具->添加
img_7d4f966ed56a502ed4f0fc935de3cdc8.png
标题输入 Get SN Token(当然也可以改成你喜欢的名字)
命令输入 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\sn.exe (即sn.exe的完整路径)
参数输入 -T $(TargetPath)
同时勾选"使用输出窗口"
完事之后,vs.net工具菜单下,应该会出一个菜单项 Get SN Token
img_6df3f70a3cefabb81389c1c9c3e7014b.png
在解决方案窗口上,选中SL类库项目,先编译通过,然后再选择"Get SN Token"菜单,就能看到对应的publickeytoken,如下图:
img_4adbb6cd8c9cfb8aef0cc2d91b9712f7.png

步骤3:SL项目引用这个dll(或SL类库),并正确勾选"通过使用应用程序库缓存减少XAP大小(R)”即可

最终在ClientBin目录下,会看到类似下面的输出:

img_8dfe7ea0f23162db74a6cf91e1157e13.png

可以看到VS已经自动将MyTools.dll打包成了zip文件,然后查看一下MySLApp.xap中的AppManifest.xaml内容

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="MySLApp" EntryPointType="MySLApp.App" RuntimeVersion="4.0.50826.0">
  <Deployment.Parts>
    <AssemblyPart x:Name="MySLApp" Source="MySLApp.dll" />
  </Deployment.Parts>
  <Deployment.ExternalParts>
    <ExtensionPart Source="MyTools.zip" />
    <ExtensionPart Source="System.Runtime.Serialization.Json.zip" />
    <ExtensionPart Source="System.Xml.Serialization.zip" />
  </Deployment.ExternalParts>
</Deployment>

注意<ExtensionPart Source="MyTools.zip" />,vs也自动为我们添加了这一行。 

提示:如果您经过以上处理,vs.net仍然无法将程序集分离成zip包,请检查项目的引用中,该程序集的“复制本地”属性是否为false,如果不是,请更改为False

img_bc847d55dba22e39931bcbd1f41557ad.png

示例源代码下载:http://files.cnblogs.com/yjmyzz/SL_App_Cache_Demo.7z 

注:应用程序缓存不适用于OOB方式

目录
相关文章
|
8月前
|
存储 缓存 NoSQL
缓存加速新玩法,让你的应用飞起来
本文主要叙述如何运用云数据库 Tair 构建缓存,助力应用提速、优化性能。
|
6月前
|
缓存 NoSQL Java
Redis应用—8.相关的缓存框架
本文介绍了Ehcache和Guava Cache两个缓存框架及其使用方法,以及如何自定义缓存。主要内容包括:Ehcache缓存框架、Guava Cache缓存框架、自定义缓存。总结:Ehcache适合用作本地缓存或与Redis结合使用,Guava Cache则提供了更灵活的缓存管理和更高的并发性能。自定义缓存可以根据具体需求选择不同的数据结构和引用类型来实现特定的缓存策略。
354 16
Redis应用—8.相关的缓存框架
|
6月前
|
缓存 NoSQL PHP
用装饰器模式实现多层缓存:让PHP应用更快更稳
通过装饰器模式实现PHP多层缓存架构,详解如何利用内存、Redis、文件缓存组合提升应用性能。包含设计思路、代码示例与实战效果对比,助您构建高效缓存策略。
|
10月前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
10月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
181 5
|
10月前
|
缓存 NoSQL 数据库
运用云数据库 Tair 构建缓存为应用提速,完成任务得苹果音响、充电套装等好礼!
本活动将带大家了解云数据库 Tair(兼容 Redis),通过体验构建缓存以提速应用,完成任务,即可领取罗马仕安卓充电套装,限量1000个,先到先得。邀请好友共同参与活动,还可赢取苹果 HomePod mini、小米蓝牙耳机等精美好礼!
|
11月前
|
存储 缓存 数据库
缓存技术有哪些应用场景呢
【10月更文挑战第19天】缓存技术有哪些应用场景呢
|
11月前
|
缓存 移动开发 前端开发
HTML5 应用程序缓存详解
HTML5 应用程序缓存(Application Cache)通过缓存 HTML、JavaScript、CSS 和图像等资源,使 Web 应用能在离线状态下运行。它利用 Manifest 文件(`.appcache`)定义缓存资源列表,浏览器会在加载页面时下载并缓存这些资源。此外,应用程序缓存还提供了事件处理机制,允许开发者监控缓存状态并进行手动管理。尽管这一技术已被视为过时,建议使用 Service Workers 和 Cache API 等现代替代方案来实现更强大的离线功能和缓存控制。
|
11月前
|
缓存 NoSQL Java
Springboot自定义注解+aop实现redis自动清除缓存功能
通过上述步骤,我们不仅实现了一个高度灵活的缓存管理机制,还保证了代码的整洁与可维护性。自定义注解与AOP的结合,让缓存清除逻辑与业务逻辑分离,便于未来的扩展和修改。这种设计模式非常适合需要频繁更新缓存的应用场景,大大提高了开发效率和系统的响应速度。
294 2
|
12月前
|
机器学习/深度学习 缓存 NoSQL
深度学习在图像识别中的应用与挑战后端开发中的数据缓存策略
本文深入探讨了深度学习技术在图像识别领域的应用,包括卷积神经网络(CNN)的原理、常见模型如ResNet和VGG的介绍,以及这些模型在实际应用中的表现。同时,文章也讨论了数据增强、模型集成等改进性能的方法,并指出了当前面临的计算资源需求高、数据隐私等挑战。通过综合分析,本文旨在为深度学习在图像识别中的进一步研究和应用提供参考。 本文探讨了后端开发中数据缓存的重要性和实现方法,通过具体案例解析Redis在实际应用中的使用。首先介绍了缓存的基本概念及其在后端系统性能优化中的作用;接着详细讲解了Redis的常见数据类型和应用场景;最后通过一个实际项目展示了如何在Django框架中集成Redis,