Execute multiple Geoprocessing Tools Async in SOE

957
2
11-23-2018 06:05 AM
RichardReinicke
Occasional Contributor II

Hi,

I`m currently working on a more complex SOE process that runs on our latest ArcGIS Server version 10.6.1 much slower then ever before. The process includes several Raster Geoprocessing Functions which are time consuming and currently processed synchronously without 64 bit background processing. I would really like to migrate this to an asynchronous background process but I can't figure out how to bring this together. Async/await doesn't seem to work with the common SOE project layout.

This is the major logic:

RestOperation doMyJob = new RestOperation("doMyJob", new string[] { "param1", "param2", "param3", "param4", "param5", "param6", "param7", "param8" }, new string[] { "json" }, doMyJobOperationHandler);private byte[] doMyJobOperationHandler(NameValueCollection boundVariables,
                                                   JsonObject operationInput,
                                                       string outputFormat,
                                                       string requestProperties,
                                                   out string responseProperties)
{
    ... do a lot of stuff here
    return getCutFillAreas(p_strDatasetName, p_Polygon, b_dBaseZ, p_dZFactor, p_bCreateFC, p_strConstantRasterPath, p_strCutFillRasterPath, p_strClippedRasterPath);
}‍‍‍‍‍‍‍‍‍‍‍

private byte[] getCutFillAreas(string paramA, IPolygon4 polygon, double z, double zFactor, bool createFC, string constRasterPath, string cutFillRasterPath, string clippedRasterPath)
{
    JsonObject resultJsonObject = new JsonObject();
    ...do a lot of stuff here
    executeClipTool((IRaster) iGeoDataset, clippedRasterPath, clippingEnv)
    ...continue here after clipping is done
    executeAnotherGeoprocessingTool();
    ...continue
    return Encoding.UTF8.GetBytes(someJsonObject.ToJson());
}

private void executeClipTool(IRaster inRaster, string outRasterPath, IEnvelope rectangle)
{
    Geoprocessor GP = new Geoprocessor();
    Clip l_clipTool = new Clip();
    l_clipTool.in_raster = inRaster;
    l_clipTool.out_raster = outRasterPath;
    l_clipTool.rectangle = Math.Round(rectangle.XMin, 0) + ", " +
                           Math.Round(p_rectangle.YMin, 0) + ", " +
                           Math.Round(p_rectangle.XMax, 0) + ", " +
                           Math.Round(p_rectangle.YMax, 0)
    executeGeoprocessingTool(GP, l_clipTool, null);
}

This is very simplified but it shows what I want to do. Basically I execute the tools synchronously and access results afterwards through file access. 

Now I want to have my main function getCutFillAreas to run executeClipTool() and other functions with Geoprocessor as asynchronous Tasks. I tried 

var result = executeClipToolAsync((IRaster) iGeoDataset, clippedRasterPath, clippingEnv).Result

with a Task<T> approach

Task<bool> clippingTask = Task.Factory.StartNew(() =>
 {
    return true;
}
return await clippingTask;

but then I get Task error.

Any help would be very appreciated!

0 Kudos
2 Replies
nicogis
MVP Frequent Contributor

Arcobjects are STA com so with TPL is only waste of time . You could try with a task scheduler ( https://devblogs.microsoft.com/pfxteam/parallelextensionsextras-tour-5-stataskscheduler/  )

RichardReinicke
Occasional Contributor II

Thank you Domenico,

interesting article, I'tll keep this in mind for future but it turned out that the low SOE / Geoprocessing tool performance was related to changed data sources.

We now totally changed our raster data sources to mosaic datasets and Image Services and therefore redesign to Image Service native functionality and ImageServer SOEs.

0 Kudos