首页 > 代码库 > 拥抱新的.Net开发框架,WPF开发人员怎样向.Net迁移
拥抱新的.Net开发框架,WPF开发人员怎样向.Net迁移
ArcGIS Runtime 10.2版本号中。将WindowsPhone 、WindowsStore以及WPF三大SDK整合成了一个全新的SDK——ArcGISRuntime SDK for Microsoft .Net Framework,简称.Net SDK。同一时候现有的WPF SDK能够继续使用。但兴许会停止更新。因此,Esri建议WPF开发人员们向.Net阵营迁移。
顾名思义,新的.NetSDK面向微软的.Net框架,曾经的WPF、Windows Phone以及Windows Store平台的开发人员们无需再分别下载安装包,直接下载.Net SDK就能够搞定。
怎样入手新的SDK?WPF已有的开发经验在新的SDK中适用吗?WPF项目怎样迁移?本博文将为你提供几个超级有用的tips。
开发人员们第一个关心的问题可能是。我在WPF开发中积累的诸多经验和技能。能否用在新的平台中?答案是非常鼓励人心的,那就是.Net SDK开发的技巧与WPF非常接近,你甚至能够将.Net SDK中的Windows Desktop API看成是对现有WPF API的升级。它们拥有很多同样的概念,甚至很多实际的类和类成员的名字都一样。只是,.Net SDK毕竟是基于最新的.NET框架,并增加了很多最新的或者流行的模型和实践在里面,比方MVVM模型和异步处理任务模型等,这意味着它们之间也有些小差别。
第二个可能关心的问题是。我须要将我现有的全部WPF项目都迁移到.Net平台上吗?答案或许是不用。迁移会导致一些问题,你必须单独考虑每一个app,评估它们是否要用到新平台中的一些新特性。
那些无需使用新特性的app无需迁移。直接使用现有的WPF API就可以。我们在未来一段时间仍会继续对现有的WPF SDK提供技术支持,帮助大家解决功能、性能及与ArcGIS的兼容性等问题。
假设app须要使用到新特性,那么最好的办法就是进行迁移。下面是一些有用的迁移方法,让大家能够更加方便的从10.2的WPF SDK迁移到.Net SDK下。
1、使用加速显示模式
1)何为加速显示?
在现有的WPF SDK中,你能够选择使用GIS技术进行优化了的地图渲染引擎,来显示整个地图,或者仅仅显示某个图层的特定子图层。这样的渲染引擎被称为“加速显示”。
虽然它也能够用来渲染其他的业务图层或者底图,可是用它来展示海量的graphic或者feature是再好只是的了。在全部的ArcGIS Runtime SDK中都有这个地图渲染引擎。在新的.Net版本号中。地图被又一次设计,使用了高性能的“加速显示”渲染模式来渲染整个地图。
2)我怎样使用加速显示?
想採用“加速显示”来渲染整个地图须要用到Map类的UseAcceleratedDisplay属性,这是推荐的途径,对应的,能够使用AcceleratedDisplayLayers group layer实现对图层的特定子图层使用“加速显示”渲染,不论什么位于该grouplayer下的图层都将使用“加速显示”渲染技术,可是记住,你仅仅能在map中加入一个AcceleratedDisplayLayers实例。
下列演示样例代码是使用WPF的标准渲染功能:
<esri:Map x:Name="MyMap" WrapAround="True"> <esri:ArcGISTiledMapServiceLayer ID="MyLayer" Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"/> <esri:GraphicsLayer ID="MyGraphics" Renderer="{StaticResource MySimpleRenderer}"/> </esri:Map> |
下列代码使用的是ArcGIS Runtime的加速显示渲染功能,使用了UseAcceleratedDisplay属性:
<esri:Map x:Name="MyMap" UseAcceleratedDisplay="True" WrapAround="True"> <esri:ArcGISTiledMapServiceLayer ID="MyLayer" Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"/> <esri:GraphicsLayer ID="MyGraphics" Renderer="{StaticResource MySimpleRenderer}"/> </esri:Map> |
3)为何加速显示模式不是WPF SDK的默认渲染模式?
这是由于,在我们将ArcGISRuntime组件增加到WPF API,并将其公布成为ArcGIS Runtime SDK for WPF之前,WPF API已经是一个独立的产品了。已经不能非常好的马上集成加速显示模式,因此我们在WPF中提供了两种渲染模式(WPF原有的普通模式和新的加速显示模式),并将加速显示模式设置为可选的而不是默认的。
4)WPF SDK中使用加速显示会有哪些问题?
你可能遇到的最大的问题是对自己定义的XAML符号的支持,由于WPF中的加速显示模式仅仅支持标准的esri symbol和渲染类型(如SimpleMarkerSymbol。SimpleRenderer等)。
而新的.Net SDK使用的是优化了的ArcGISRuntime地图渲染引擎。因此不支持自己定义的XAML符号,还有其他的图层和子图层类型不支持加速显示渲染(详细请參见ReleaseNotes),只是大部分都是支持的。
另外新的SDK中提供了CompositeSymbol复合符号类型,用户能够通过它来创建自己定义的符号。
2、异步处理使用WPF SDK 10.2支持的任务模型
1)什么是基于任务的异步处理模型?
编写高性能、响应快的应用程序须要使用基于任务的异步处理模型来应对耗时操作,或者是在单一线程里同一时候运行多个操作的情况也须要使用到它。管理多线程是件复杂的事情。因此。.Net 4.0中。微软引进了Task(任务)模型来简化多线程应用程序的处理,使得开发人员能够使用.Net Task来异步运行代码而不须要去管究竟是哪个线程在运行任务。Task同一时候也提供了很多极好的控制方式。来监听运行失败和运行成功的情况,使得它使用起来很方便:你仅仅要等待任务运行完毕就可以。当有多个Task须要运行时。须要明白它们的运行顺序,或者能够等待全部Task都运行完毕后再运行某段代码。C# 5.0版本号中更是提供了“async”、“await”等关键词来简化Task的使用。
有关async task的很多其它内容请參考AsynchronousProgramming with Async and Await。
2)在WPF API中这些Task都藏在了哪里?
ArcGIS Runtime SDK 10.2 for WPF中最引人注目的新特性之中的一个,就是不论什么异步的方法都会返回一个Task实例来表示一个操作的运行。10.2之前,API同一时候提供了同步和异步的方法来处理不论什么可能潜在的耗时操作,在10.2中。这些操作新增了一个后缀为TaskAsync的方法。如QueryTask类有一个同步运行的方法“Execute”。同一时候其异步运行的方法名在10.2之前为“ExecuteAsync”,在10.2中就变成了“ExecuteTaskAsync”。
3)我怎样使用新的异步处理方法?
在.Net 4.0中使用新的异步处理方法理论上无需不论什么辅助软件,然而,要想实现新的Task模型的全部功能,并使用“async”和“await”keyword。你必须使用.Net 4.5和VisualStudio 2012及以上的版本号,假设非要在4.0中使用,你同一时候须要下载MicrosoftAsync NuGet包。
假设你决定使用Task模型。你须要对你的代码进行一定的改动,这些改动包括取消代理的声明(如命名的event handlers, 内联匿名方法和lambda表达式),并使用awaitkeyword来调用Task的相关方法。异步方法的调用必须包括try/catch语句。由于Task在运行失败时,更有可能抛出异常而不是运行Failed事件。将捕获异常的代码放在catch语句中,这样做有两个优点:能够让你的代码更加简洁和稳定。
以下这两个样例就分别使用传统的QueryTask和10.2中的新的Task功能。
第一个样例使用基于事件的模式,使用内联lambda表达式来处理任务运行成功和失败,这样的方法下,代码显得冗余,逻辑又难以理解,在使用lambda表达式时,又要切记:必要时要移除你之前注冊过的event handler,以免它们被多次调用,这会使得对代理的声明变得复杂,让代码书写更费事。
QueryTask queryTask = new QueryTask ("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3"); // 使用内联Lambda表达式来处理运行成功事件queryTask.ExecuteCompleted += (obj, queryEventArgs) => { // Do something with results... GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphics"] as GraphicsLayer; graphicsLayer.Graphics.AddRange(queryEventArgs.FeatureSet.Features); }; // 使用内联Lambda表达式来处理运行失败事件 queryTask.Failed += (obj, taskFailedeventArgs) => { if (taskFailedeventArgs.Error != null) MessageBox.Show(taskFailedeventArgs.Error.Message); }; //在声明了内联的event handler之后调用ExecuteAsync方法 queryTask.ExecuteAsync(new Query() { Where = "1=1", ReturnGeometry = true, OutSpatialReference = MyMap.SpatialReference }); |
第二个样例使用新的QueryTask.ExecuteTaskAsync方法。它返回一个“awaitable”任务,其Result属性包括了一个QueryResult实例,返回Task<QueryResult>类型的參数。使用“await”keyword能够调用异步方法。并使得代码暂停运行直到异步任务运行完毕返回结果。这样的方式的妙处之中的一个,就是看起来代码是顺序运行的。大大增强了代码的可读性。
记住,任务运行失败时会抛出异常而不是触发“failed”事件,因此,在合适的地方使用try/catch语句很重要。
QueryTask queryTask = new QueryTask ("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3"); try { //使用awaitkeyword来调用ExecuteTaskAsync QueryResult queryResult = await queryTask.ExecuteTaskAsync(new Query() { Where = "1=1", ReturnGeometry = true, OutSpatialReference = MyMap.SpatialReference }); // Do something with results... GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphics"] as GraphicsLayer; graphicsLayer.Graphics.AddRange(queryResult.FeatureSet.Features); } catch (Exception ex) { // Handle exception } |
在WPF SDK 10.2版本号中。异步处理支持基于事件( event-based)和基于任务(Task-based)两种模型,但在新的.Net SDK中仅仅支持基于任务的模型,因此WPF开发人员在异步处理的时候採用任务模型不仅能够简化代码,还能够很方便的进行项目迁移。
3、使用“using”指令而不是全然限定的命名空间
这是一个简单的小提示。或许你早就開始这么做了,可是它的确值得注意,它会节省你非常多时间。新的Windows Desktop API的很多类型与现有的WPF API中的类型具有同样的类名,可是它们使用不同的命名空间。因此,使用using指令能够去掉ESRI.ArcGIS.Client.*程序集,而加上Esri.ArcGISRuntime.*程序集,这样,迁移之后更新一下命名空间。又一次编译一下代码就可以。
在现实中。这两个API中会有各种差异。使得你的代码必须经过适当的改动才干编译成功。但採用这个建议肯定能大幅提高你代码迁移的速度。更新信息请參考usingDirective (C# Reference)。
在您的代码中,仅仅要有可能,我们强烈推荐你避免使用全然限定的命名空间而使用using指令,如:
using ESRI.ArcGIS.Client.Tasks; … namespace MyNamespace { public partial class MainWindow : Window { QueryTask myQueryTask = new QueryTask(); … } } |
当项目须要迁移到新的WindowsDesktop API中时。你仅仅须要简单的改动命名空间就可以:
using Esri.ArcGISRuntime.Tasks.Query; … namespace MyNamespace { public partial class MainWindow : Window { QueryTask myQueryTask = new QueryTask(); … } } |
假设您正在计划将一个WPFSDK开发的项目迁移到新的.Net SDK中的话,使用上面3个小技巧可以使得你迁移更加easy,迁移后的代码更加工整,新的SDK已经公布,我们诚恳的期待您花费一点时间来试用一下,相信它能带给你更好的开发体验。
拥抱新的.Net开发框架,WPF开发人员怎样向.Net迁移