MultiThreading / Parallel Processing in ArcGIS Pro AddIn

1827
1
11-04-2019 08:14 AM
GovindaGross
New Contributor

Hello,

I am working on an ArcGIS 2.4.1 Pro AddIn that processes CPU-intensive tasks. One of the tasks is to create Polygons from parts of different PolyLines, which I achieved with the following code (shortened to the minimal relevant part):

PolylineBuilder polylineBuilder = new PolylineBuilder(SpatialReference);
polylineBuilder.AddParts(contourPolyLine.Parts);
polylineBuilder.SplitAtDistance(splitDistance, falsetrue);
var newPolygon3D = PolygonBuilder.CreatePolygon(polylineBuilder.ToGeometry()
                     .Copy3DCoordinatesToList(), SpatialReference);

This works just fine by itself, but took 40 minutes to process for about 3.000 objects. As this is run within QueuedTask.Run(async () =>...), ArcGIS Pro only utilized 1 CPU core of my 8 core machine. All attempts of separating the work and running several parallel tasks failed so far, because PolylineBuilder can not be used in a regular Task.Run(...)-Thread (Exception is thrown: "This object must be created within the lambda passed to QueuedTask.Run, or on a compatible STA thread.").

I had a look at ProConcepts Framework · Esri/arcgis-pro-sdk Wiki · GitHub  and searched the community samples but couldn't find a similar scenario.

In another ArcGIS AddIn I was able to use 100% of the CPU by creating multiple threads that each take a part of the workload, but in that case I had only calculations with regular managed code and no ArcGIS Pro Tools were involved:

await Task.WhenAll(Enumerable.Range(1, Environment.ProcessorCount).Select(c => Task.Run( () => { DoWork(); }

Is there a solution to utilize the full CPU also for jobs that use ArcGIS.Core.Geometry Tools/Classes like PolylineBuilder?

Any hint or example would be appreciated.

Cheers

1 Reply
UmaHarano
Esri Regular Contributor

To use the STA thread, you can use the StartSTATask method in the attached TaskUtils.cs file. Here is the usage for the method:

await TaskUtils.StartSTATask<int>(() => {
                        //Do Polygonbuilder task here.
                    });‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos