dotMorten

Silverlight/WPF/WP7 Async tasks - fESRI.ArcGIS.Client

Apr 11th, 2012
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.63 KB | None | 0 0
  1. using System;
  2. using System.Reflection;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. using ESRI.ArcGIS.Client.Tasks;
  6.  
  7. namespace ESRI.Samples.Async.Tasks
  8. {
  9.     public static partial class Extensions
  10.     {
  11.     ///////////////////////////////////////
  12.     // Base implementation
  13.     ///////////////////////////////////////
  14.    
  15.     private static PropertyInfo QueryCountEventArgsCountProperty = typeof(QueryCountEventArgs).GetProperty("Count");
  16.         private static PropertyInfo QueryEventArgsFeaturesetProperty = typeof(QueryEventArgs).GetProperty("FeatureSet");
  17.         private static PropertyInfo RelationshipEventArgsResultProperty = typeof(RelationshipEventArgs).GetProperty("Result");
  18.         private static EventInfo QueryExecuteCompletedEvent = typeof(QueryTask).GetEvent("ExecuteCompleted");
  19.         private static EventInfo QueryExecuteCountCompletedEvent = typeof(QueryTask).GetEvent("ExecuteCountCompleted");
  20.         private static EventInfo QueryExecuteRelationshipQueryCompletedEvent = typeof(QueryTask).GetEvent("ExecuteRelationshipQueryCompleted");
  21.            
  22.         public static Task<FeatureSet> ExecuteTaskAsync(this QueryTask task, Query query)
  23.         {
  24.             return ExecuteTaskAsync(task, query, CancellationToken.None);
  25.         }
  26.  
  27.         public static Task<FeatureSet> ExecuteTaskAsync(this QueryTask task, Query query, CancellationToken cancellationToken)
  28.         {
  29.             return HandleTaskAndResult<FeatureSet, QueryEventArgs>(
  30.                 task, QueryExecuteCompletedEvent, QueryEventArgsFeaturesetProperty,
  31.                 () => { task.ExecuteAsync(query); }, cancellationToken);
  32.         }
  33.        
  34.         public static Task<int> ExecuteCountTaskAsync(this QueryTask task, Query query)
  35.         {
  36.             return ExecuteCountTaskAsync(task, query, CancellationToken.None);
  37.         }
  38.  
  39.         public static Task<int> ExecuteCountTaskAsync(this QueryTask task, Query query, CancellationToken cancellationToken)
  40.         {
  41.             return HandleTaskAndResult<int, QueryCountEventArgs>(
  42.                 task, QueryExecuteCountCompletedEvent, QueryCountEventArgsCountProperty,
  43.                 () => { task.ExecuteCountAsync(query); }, cancellationToken);
  44.         }
  45.  
  46.         public static Task<RelationshipResult> ExecuteRelationshipQueryTaskAsync(this QueryTask task, RelationshipParameter parameter)
  47.         {
  48.             return ExecuteRelationshipQueryTaskAsync(task, parameter, CancellationToken.None);
  49.         }
  50.  
  51.         public static Task<RelationshipResult> ExecuteRelationshipQueryTaskAsync(this QueryTask task, RelationshipParameter parameter, CancellationToken cancellationToken)
  52.         {
  53.             return HandleTaskAndResult<RelationshipResult, RelationshipEventArgs>(
  54.                 task, QueryExecuteRelationshipQueryCompletedEvent, RelationshipEventArgsResultProperty,
  55.                 () => { task.ExecuteRelationshipQueryAsync(parameter); }, cancellationToken);
  56.         }
  57.  
  58.    
  59.     ///////////////////////////////////////
  60.     // Base implementation
  61.     ///////////////////////////////////////
  62.         private static System.Threading.Tasks.Task<T> HandleTaskAndResult<T,S>(
  63.                 this TaskBase task,
  64.                 EventInfo completedEvent,
  65.                 PropertyInfo resultProperty,
  66.                 Action ExecuteMethod,
  67.                 CancellationToken cancellationToken)
  68.             where S : TaskEventArgs
  69.         {
  70.             var innertask = HandleTask<S>(task, completedEvent, ExecuteMethod, cancellationToken);
  71.             TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
  72.             innertask.ContinueWith((e) =>
  73.             {
  74.                 if (e.IsCompleted)
  75.                     tcs.SetResult((T)resultProperty.GetValue(e.Result, null));
  76.                 else if (e.IsFaulted)
  77.                     tcs.SetException(e.Exception);
  78.                 else if (e.IsCanceled)
  79.                     tcs.SetCanceled();
  80.             });
  81.             return tcs.Task;
  82.         }
  83.  
  84.         private static System.Threading.Tasks.Task<T> HandleTask<T>(
  85.             this TaskBase task,
  86.             EventInfo completedEvent,
  87.             Action ExecuteMethod,
  88.             CancellationToken cancellationToken)
  89.             where T : TaskEventArgs
  90.         {
  91.             TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
  92.             EventHandler<T> completedHandler = null;
  93.             EventHandler<TaskFailedEventArgs> failedHandler = null;
  94.             Action unregister = () =>
  95.             {
  96.                 completedEvent.RemoveEventHandler(task, completedHandler);
  97.                 task.Failed -= failedHandler;
  98.             };
  99.             if (cancellationToken.CanBeCanceled)
  100.                 cancellationToken.Register(() =>
  101.                 {
  102.                     unregister();
  103.                     task.CancelAsync();
  104.                 });
  105.  
  106.             completedHandler = delegate(object sender, T e)
  107.             {
  108.                 unregister();
  109.                 if (!cancellationToken.IsCancellationRequested)
  110.                     tcs.SetResult(e);
  111.             };
  112.             failedHandler = delegate(object sender, TaskFailedEventArgs e)
  113.             {
  114.                 unregister();
  115.                 tcs.SetException(e.Error);
  116.             };
  117.  
  118.             completedEvent.AddEventHandler(task, completedHandler);
  119.             task.Failed += failedHandler;
  120.             try
  121.             {
  122.                 ExecuteMethod();
  123.             }
  124.             catch (System.Exception ex)
  125.             {
  126.                 unregister();
  127.                 tcs.SetException(ex);
  128.             }
  129.             return tcs.Task;
  130.         }
  131.     }
  132. }
Advertisement
Add Comment
Please, Sign In to add comment