How to run an asynchronous gp service from ArcGIS Pro SDK?

851
5
Jump to solution
04-09-2020 12:20 PM
JamesGough
New Contributor III

I am new to the ArcGIS Pro SDK. I am attempting to run a Python toolbox tool that I published to ArcGIS Server as a GPServer. The task is asynchronous (esriExecutionTypeAsynchronous).

I have tried running the tool using await Geoprocessing.ExecuteToolAsync(), this successfully submits the job, and the job is successful. However, my code does not actually wait until the job finishes. It just submits it, and then continues.

Is there way to submit a job and check its status until completion using the Geoprocessing namespace or any other function in the SDK? Or do I just need to do this using the ArcGIS Server REST API?

The gist of my code:

protected override async void OnClick()
 {
   // Setup Progress dialog
   var progDlg = new ProgressDialog("Running Tool", "Cancel", 100, true);
   progDlg.Show();
   var progSrc = new CancelableProgressorSource(progDlg);
   // Tool parameters
   string tool_path = @"path to my tool on server using a .ags file";
   string flags_fc = @"path to a feature class";
   string barriers_fc = @"path to a feature class";
   string skip_locations = @"path to a feature class";
   var parameters = Geoprocessing.MakeValueArray(flags_fc, barriers_fc, skip_locations);
   // Run the Tool
   var result = await Geoprocessing.ExecuteToolAsync(tool_path, parameters, null, new 
       CancelableProgressorSource(progDlg).Progressor, GPExecuteToolFlags.Default);
   progDlg.Hide();
   Geoprocessing.ShowMessageBox(result.Messages, "GP Messages", result.IsFailed ? 
   GPMessageBoxStyle.Error : GPMessageBoxStyle.Default);
 }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Thanks,

James

0 Kudos
1 Solution

Accepted Solutions
GintautasKmieliauskas
Regular Contributor

Hi James,

Have you tried like this:

                    var parameters = Geoprocessing.MakeValueArray(fullSpec, fieldName);
                    var cts = new CancellationTokenSource();
                    var results = Geoprocessing.ExecuteToolAsync("management.DeleteField", parameters, null, cts.Token,
                        (eventName, o) =>
                        {
                            System.Diagnostics.Debug.WriteLine($@"GP event: {eventName}");
                            if (eventName == "OnMessage")
                            {
                                System.Diagnostics.Debug.WriteLine($@"Msg: {o}");
                            }
                        });
If you want to wait until your job finishes you can do like this:
               var parameters = Geoprocessing.MakeValueArray(sInputPath);
                var gpResult = Geoprocessing.ExecuteToolAsync("Delete_management", parameters, null, CancelableProgressor.None,
                        GPExecuteToolFlags.None);
                gpResult.Wait();
                return !gpResult.Result.IsFailed;
Or you can combine both.

View solution in original post

0 Kudos
5 Replies
GintautasKmieliauskas
Regular Contributor

Hi James,

Have you tried like this:

                    var parameters = Geoprocessing.MakeValueArray(fullSpec, fieldName);
                    var cts = new CancellationTokenSource();
                    var results = Geoprocessing.ExecuteToolAsync("management.DeleteField", parameters, null, cts.Token,
                        (eventName, o) =>
                        {
                            System.Diagnostics.Debug.WriteLine($@"GP event: {eventName}");
                            if (eventName == "OnMessage")
                            {
                                System.Diagnostics.Debug.WriteLine($@"Msg: {o}");
                            }
                        });
If you want to wait until your job finishes you can do like this:
               var parameters = Geoprocessing.MakeValueArray(sInputPath);
                var gpResult = Geoprocessing.ExecuteToolAsync("Delete_management", parameters, null, CancelableProgressor.None,
                        GPExecuteToolFlags.None);
                gpResult.Wait();
                return !gpResult.Result.IsFailed;
Or you can combine both.
0 Kudos
JamesGough
New Contributor III

Hi Gintautas,

Thanks for the response!

So if I understand, the first option you showed uses a callback function that should be called when the job finishes.

The second option uses the Task.Wait method to wait until the task finishes. Is this blocking or does it automatically spawn a new thread?

thanks,

James

0 Kudos
GintautasKmieliauskas
Regular Contributor

HI James,

More info about first option:

ArcGIS Pro 2.5 API Reference Guide 

0 Kudos
JamesGough
New Contributor III

Thanks that is helpful, the Pro SDK documentation is a little confusing to navigate

0 Kudos
JamesGough
New Contributor III

The GPToolExecuteEventHandler Delegate options seems to be working, thanks!

0 Kudos