//Use the ArcGIS REST API to create a profile line based on the input geometry
        public async Task <Polyline> GetProfileLine(Geometry geometry)
        {
            try
            {
                string requestUrlBase = @"http://elevation.arcgis.com/arcgis/rest/services/Tools/Elevation/GPServer/Profile/";

                //Create the token to use
                TokenService elevationServices = new TokenService();
                _token = await elevationServices.GenerateTokenAsync();

                #region Submit a profile task to be executed asynchronously. A unique job ID will be assigned for the transaction.
                string oidField          = "OID";
                string lengthField       = "Shape_Length";
                string InputLineFeatures = CreateInputLineFeaturesJson(geometry, oidField, lengthField);
                string additonalParams   = "&ProfileIDField=" + oidField + "&DEMResolution=FINEST&MaximumSampleDistance=10&MaximumSampleDistanceUnits=Kilometers&returnZ=true&returnM=true&env%3AoutSR=102100&env%3AprocessSR=102100&f=json";
                string profileServiceUrl = string.Format("{0}submitJob?token={1}&InputLineFeatures={2}{3}", requestUrlBase, _token.AccessToken, InputLineFeatures, additonalParams);

                System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(profileServiceUrl);
                webRequest.Timeout = 0xea60;
                System.Net.WebResponse response = await webRequest.GetResponseAsync();

                #endregion

                #region Use the jobId to check the status of the job. Keep checking if the jobStatus is not "Succeeded"
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(JobStatus));
                _jobStatus = (JobStatus)serializer.ReadObject(response.GetResponseStream() as Stream);
                while (_jobStatus.Status.Contains("Executing") || _jobStatus.Status.Contains("esriJobWaiting") || _jobStatus.Status.Contains("Submitted"))
                {
                    string statusUrl = string.Format("{0}jobs/{1}?f=pjson&token={2}", requestUrlBase, _jobStatus.Id, _token.AccessToken);
                    webRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(statusUrl);
                    response   = await webRequest.GetResponseAsync();

                    _jobStatus = (JobStatus)serializer.ReadObject(response.GetResponseStream());
                }
                #endregion

                #region The job has successfully completed. Use the jobId to retrieve the result, then use the result to create a profile line
                if (_jobStatus.Status.Contains("Succeeded"))
                {
                    string resultsUrl = string.Format("{0}jobs/{1}/results/OutputProfile?returnZ=true&returnM=true&f=pjson&token={2}", requestUrlBase, _jobStatus.Id, _token.AccessToken);
                    webRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(resultsUrl);
                    response   = await webRequest.GetResponseAsync();

                    serializer = new DataContractJsonSerializer(typeof(OutputProfile));

                    //Parse the result as the output profile line
                    _outputProfileLine = (OutputProfile)serializer.ReadObject(response.GetResponseStream());
                    _outputProfileLine.FeatureSet.HasM = true;
                    _outputProfileLine.FeatureSet.HasZ = true;

                    //Create a polyline (profile) from the geometry of the output profile line
                    Polyline profile = new Polyline();
                    foreach (var points in _outputProfileLine.FeatureSet.Features.FirstOrDefault().Geometry.Paths)
                    {
                        PointCollection collection = new PointCollection();
                        foreach (var point in points)
                        {
                            collection.Add(
                                new MapPoint(
                                    Convert.ToDouble(point[0]), //[0] is x
                                    Convert.ToDouble(point[1]), //[1] is x
                                    Convert.ToDouble(point[2]), //[2] is z
                                    Convert.ToDouble(point[3]), //[3] is m
                                    new ESRI.ArcGIS.Client.Geometry.SpatialReference(102100)));
                        }
                        profile.Paths.Add(collection);
                    }

                    return(profile);
                }
                return(null);

                #endregion
            }
            catch (Exception)
            {
                return(null);
            }
        }
    //Use the ArcGIS REST API to create a profile line based on the input geometry
    public async Task<Polyline> GetProfileLine(Geometry geometry)
    {
      try
      {
        string requestUrlBase = @"http://elevation.arcgis.com/arcgis/rest/services/Tools/Elevation/GPServer/Profile/";

        //Create the token to use
        TokenService elevationServices = new TokenService();
        _token = await elevationServices.GenerateTokenAsync();

        #region Submit a profile task to be executed asynchronously. A unique job ID will be assigned for the transaction.
        string oidField = "OID";
        string lengthField = "Shape_Length";
        string InputLineFeatures = CreateInputLineFeaturesJson(geometry, oidField, lengthField);
        string additonalParams = "&ProfileIDField=" + oidField + "&DEMResolution=FINEST&MaximumSampleDistance=10&MaximumSampleDistanceUnits=Kilometers&returnZ=true&returnM=true&env%3AoutSR=102100&env%3AprocessSR=102100&f=json";
        string profileServiceUrl = string.Format("{0}submitJob?token={1}&InputLineFeatures={2}{3}", requestUrlBase, _token.AccessToken, InputLineFeatures, additonalParams);

        System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(profileServiceUrl);
        webRequest.Timeout = 0xea60;
        System.Net.WebResponse response = await webRequest.GetResponseAsync(); 
        #endregion

        #region Use the jobId to check the status of the job. Keep checking if the jobStatus is not "Succeeded"
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(JobStatus));
        _jobStatus = (JobStatus)serializer.ReadObject(response.GetResponseStream() as Stream);
        while (_jobStatus.Status.Contains("Executing") || _jobStatus.Status.Contains("esriJobWaiting") || _jobStatus.Status.Contains("Submitted"))
        {
          string statusUrl = string.Format("{0}jobs/{1}?f=pjson&token={2}", requestUrlBase, _jobStatus.Id, _token.AccessToken);
          webRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(statusUrl);
          response = await webRequest.GetResponseAsync();
          _jobStatus = (JobStatus)serializer.ReadObject(response.GetResponseStream());
        } 
        #endregion

        #region The job has successfully completed. Use the jobId to retrieve the result, then use the result to create a profile line 
        if (_jobStatus.Status.Contains("Succeeded"))
        {
          string resultsUrl = string.Format("{0}jobs/{1}/results/OutputProfile?returnZ=true&returnM=true&f=pjson&token={2}", requestUrlBase, _jobStatus.Id, _token.AccessToken);
          webRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(resultsUrl);
          response = await webRequest.GetResponseAsync();

          serializer = new DataContractJsonSerializer(typeof(OutputProfile));

          //Parse the result as the output profile line
          _outputProfileLine = (OutputProfile)serializer.ReadObject(response.GetResponseStream());
          _outputProfileLine.FeatureSet.HasM = true; 
          _outputProfileLine.FeatureSet.HasZ = true;

          //Create a polyline (profile) from the geometry of the output profile line
          Polyline profile = new Polyline();
          foreach (var points in _outputProfileLine.FeatureSet.Features.FirstOrDefault().Geometry.Paths)
          {
            PointCollection collection = new PointCollection();
            foreach (var point in points)
              collection.Add(
                new MapPoint(
                  Convert.ToDouble(point[0]), //[0] is x
                  Convert.ToDouble(point[1]), //[1] is x
                  Convert.ToDouble(point[2]), //[2] is z
                  Convert.ToDouble(point[3]), //[3] is m
                  new ESRI.ArcGIS.Client.Geometry.SpatialReference(102100)));   
            profile.Paths.Add(collection);
          }

          return profile;
        }
        return null;
        #endregion
      }
      catch (Exception)
      {
        return null;
      }
    }