Silverlight 5 項目使用async/await
.Net 4.5 提供了 async/await 讓異步編程回歸同步, 不過,async/await 不是只能在 .Net 4.5 下才能使用, 通過使用 Async Targeting Pack 就可以在 .Net 4.0 以及 Silverlight 5 項目中使用 async/await。
先來看一段 Silverlight 代碼, 不使用 async/await 時是這樣子的:
- private void DistanceTestButtonClick(object sender, RoutedEventArgs routedEventArgs) {
- // 假設(shè)這是用戶輸入的坐標(biāo)
- var point1 = GeometryUtil.CreateMapPointWgs84(113.3, 23.07);
- // 假設(shè)用戶輸入目的地坐標(biāo)
- var point2 = GeometryUtil.CreateMapPointWgs84(110.3, 20);
- // 全局地圖控件
- var map = App.ObjContainer.Resolve(typeof(Map));
- // 從當(dāng)前 UI 上下文創(chuàng)建 TaskScheduler
- var uiContext = TaskScheduler.FromCurrentSynchronizationContext();
- // 創(chuàng)建三個幾何服務(wù)
- var geoSvc1 = GeoFactory.CreateGeometryService();
- var geoSvc2 = GeoFactory.CreateGeometryService();
- var geoSvc3 = GeoFactory.CreateGeometryService();
- // 將用戶輸入的坐標(biāo)投影為地圖的坐標(biāo)系坐標(biāo)
- var task1 = geoSvc1.ProjectPointAsync(point1, map.SpatialReference);
- task1.ContinueWith(t1 => {
- point1 = task1.Result;
- // 目的地坐標(biāo)投影為地圖坐標(biāo)
- var task2 = geoSvc2.ProjectPointAsync(point2, map.SpatialReference);
- task2.ContinueWith(t2 => {
- point2 = task2.Result;
- var buffParam = this.CreateBufferParameters(point2);
- var buffTask = geoSvc3.BufferTaskAsync(buffParam);
- // 做一次緩沖查詢
- buffTask.ContinueWith(t3 => {
- var buffGeometry = buffTask.Result.First();
- var disParam = new DistanceParameters {
- DistanceUnit = LinearUnit.Meter,
- Geodesic = true
- };
- // 求距離
- var disTask1 = geoSvc1.DistanceTaskAsync(point1, point2, disParam);
- disTask1.ContinueWith(t4 => {
- var disTask2 = geoSvc2.DistanceTaskAsync(point1, buffGeometry.Geometry, disParam);
- disTask2.ContinueWith(t5 => {
- //***求得最終距離
- var dis1 = disTask1.Result;
- var dis2 = disTask2.Result;
- }, uiContext);
- }, uiContext);
- }, uiContext);
- }, uiContext);
- }, uiContext);
- }
看上面的代碼,做Silverlight 開發(fā)的可真?zhèn)黄鸢?,Silverlight 閹割了所有的同步方法,只能做異步查詢,本來是可以放在后臺線程中模擬同步的,可偏偏 ArcGIS 提供的 Silverlight API 在回調(diào)函數(shù)中創(chuàng)建了 UI 元素以及 DepedencyObject ,想放到后臺線程中計算也不行,真是悲劇。
下面就請出 Async Targeting Pack 來拯救一下吧, 打開 NuGet 管理器, 輸入 await 查詢, 找到 Async Targeting Pack for Visual Studio 11 , 然后下載并添加引用到 Silverlight 項目, 開始用 async/await 改造上面的代碼, 最終的結(jié)果如下, 看看是不是清爽了好多呢?
- async private void DistanceTestButtonClick(object sender, RoutedEventArgs routedEventArgs) {
- var point1 = GeometryUtil.CreateMapPointWgs84(113.3, 23.07);
- var point2 = GeometryUtil.CreateMapPointWgs84(110.3, 20);
- var map = App.ObjContainer.Resolve(typeof(Map));
- var geoSvc1 = GeoFactory.CreateGeometryService();
- var geoSvc2 = GeoFactory.CreateGeometryService();
- var geoSvc3 = GeoFactory.CreateGeometryService();
- point1 = await geoSvc1.ProjectGeometryAsync(point1, map.SpatialReference) as MapPoint;
- point2 = await geoSvc2.ProjectGeometryAsync(point2, map.SpatialReference) as MapPoint;
- var buffParam = this.CreateBufferParameters(point2);
- var buffGeometry = (await geoSvc3.BufferTaskAsync(buffParam)).First();
- var disParam = new DistanceParameters {
- DistanceUnit = LinearUnit.Meter,
- Geodesic = true
- };
- var dist1 = await geoSvc1.DistanceTaskAsync(point1, point2, disParam);
- var dist2 = await geoSvc2.DistanceTaskAsync(point1, buffGeometry.Geometry, disParam);
- var d = dist2 - dist1;
- }
這樣編譯出來的 xap 包只是多了一個 dll, 依然可以在 Silverlight5 下運行, 客戶端不需要安裝任何軟件。
大家趕快升級 VS2012 吧, 異步編程回歸同步了!
原文鏈接:http://www.cnblogs.com/beginor/archive/2012/07/21/2602838.html
【編輯推薦】