Microsoft Silverlight是一个跨浏览器的、跨平台的插件,为网络带来下一代基于.NET的媒体体验和丰富的交互式应用程序。Silverlight提供灵活的编程模型,并可以很方便地集成到现有的网络应用程序中。
这里我们将讨论如何分离庞大的应用程序让用户的体验更佳:假如我们有一个5M的Silverlight程序,客户的下载速度为128Kb/s大约下载时间为40s,让用户面对silverlight默认的加载界面痴痴发呆。我在这里推荐一种动态加载的解决方案:Loader+Application+IsolatedStorage
1.首先独立创建一个Application就是我们的应用系统
2.为我们的Application创建一个精简的Loader(silverlight App),Loader的主要作用就是检查服务器端的版本和本地IsolatedStorage的版本,发现服务器新的版本则主动请求下载,否则就从IsolatedStorage读取应用程序。这样我们就可以创建丰富的加载界面(不要搞大了)。
下面附上关键代码:
WebClient client = new WebClient();
client.OpenReadAsync(new Uri(string.Format("{0}?{1}", "Silverlight.App.xap", DateTime.Now.Ticks), UriKind.Relative));
client.OpenReadCompleted += (o, args) =>
{
if (args.Error == null)
{
StreamResourceInfo xapResource = new StreamResourceInfo(args.Result, null);
StreamResourceInfo appManifest = Application.GetResourceStream(xapResource, new Uri("AppManifest.xaml", UriKind.Relative));
XmlReader xmlReader = XmlReader.Create(appManifest.Stream, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore });
Assembly appAssembly = null;
List<Assembly> list = new List<Assembly>();
while (!xmlReader.EOF)
{
if (xmlReader.ReadToFollowing("AssemblyPart"))
{
string dll = xmlReader.GetAttribute("Source");
StreamResourceInfo dllStreamInfo = Application.GetResourceStream(xapResource, new Uri(dll, UriKind.Relative));
AssemblyPart part = new AssemblyPart();
Assembly assembly = part.Load(dllStreamInfo.Stream);
list.Add(assembly);
}
}
appAssembly = list.SingleOrDefault((a) =>
a.FullName.StartsWith("Silverlight.App,")
);
if (appAssembly != null)
{
Type type = appAssembly.GetType("Silverlight.App.MainPage");
if (type != null)
{
UserControl control = Activator.CreateInstance(type) as UserControl;
if (control != null)
{
Panel root = (Panel)VisualTreeHelper.GetChild(App.Current.RootVisual, 0);
root.Children.Clear();
root.Children.Add(control);
}
}
}
}
};
client.OpenReadAsync(new Uri(string.Format("{0}?{1}", "Silverlight.App.xap", DateTime.Now.Ticks), UriKind.Relative));
client.OpenReadCompleted += (o, args) =>
{
if (args.Error == null)
{
StreamResourceInfo xapResource = new StreamResourceInfo(args.Result, null);
StreamResourceInfo appManifest = Application.GetResourceStream(xapResource, new Uri("AppManifest.xaml", UriKind.Relative));
XmlReader xmlReader = XmlReader.Create(appManifest.Stream, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore });
Assembly appAssembly = null;
List<Assembly> list = new List<Assembly>();
while (!xmlReader.EOF)
{
if (xmlReader.ReadToFollowing("AssemblyPart"))
{
string dll = xmlReader.GetAttribute("Source");
StreamResourceInfo dllStreamInfo = Application.GetResourceStream(xapResource, new Uri(dll, UriKind.Relative));
AssemblyPart part = new AssemblyPart();
Assembly assembly = part.Load(dllStreamInfo.Stream);
list.Add(assembly);
}
}
appAssembly = list.SingleOrDefault((a) =>
a.FullName.StartsWith("Silverlight.App,")
);
if (appAssembly != null)
{
Type type = appAssembly.GetType("Silverlight.App.MainPage");
if (type != null)
{
UserControl control = Activator.CreateInstance(type) as UserControl;
if (control != null)
{
Panel root = (Panel)VisualTreeHelper.GetChild(App.Current.RootVisual, 0);
root.Children.Clear();
root.Children.Add(control);
}
}
}
}
};
上面代码还缺少一个部分就是将目标应用程序的App资源给copy到当前App中,否则会报找不到对应资源的异常。时间紧促,后面把代码补上。
小弟献丑,欢迎各位提出宝贵的意见,大家一起讨论学习。