Issue with Geoprocessor.ExecuteAsync()

2800
1
06-11-2013 02:53 PM
TerryGiles
Occasional Contributor III
I'm trying to follow the asynch pattern described in the SDK sample "Executing geoprocessing tools in the background" (online  here) but keep getting a COMException in my ToolExecuted handler when I try dequeque the next tool call ExecuteAsync.

Event handlers are set in the constructor of the class -
            _gp = new Geoprocessor();
            _gp.ToolExecuted += new EventHandler<ToolExecutedEventArgs>(GPToolExecuted);
            _gp.ToolExecuting += new EventHandler<ToolExecutingEventArgs>(GPToolExecuting);


The first tool in my Queque is called in this method -
internal void RunTool(Queue<GPFunction> GPFuncs)
        {
            //Runs a TauDEM GP tool.  Input GPFunction queue can also contain conversion & clean up GP tasks
            //since TauDEM only reads/write UnCompressed TIFFs

            GPFunction gpfunct = null;

            try
            {
                _gpfunctions = GPFuncs;
                gpfunct = _gpfunctions.Dequeue();

                _gp.OverwriteOutput = true; // gpfunct.OverwriteOutput;
                _gp.AddOutputsToMap = gpfunct.AddtoMap;
                _gp.AddToolbox(_strTauDEM + "TauDEM5Arc\\TauDEM Tools.tbx");

                if (gpfunct.Environments != null)
                {
                    foreach (KeyValuePair<string, object> kvp in gpfunct.Environments)
                    {
                        _gp.SetEnvironmentValue(kvp.Key, kvp.Value);
                    }
                }

                _gp.ExecuteAsync(gpfunct.ToolName, gpfunct.ToolParams);
                
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Error in RunTool");
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
}


The first tool (usally CopyRaster to convert to Tif which is the only input a custom tool will take) fires and and when it completes it will go into ToolExecuted but bombs on the ExecuteAsync

        private void GPToolExecuted(object sender, ToolExecutedEventArgs e)
        {
            //Fires when a GP tool completes (fail or success)

            IGeoProcessorResult2 result = e.GPResult as IGeoProcessorResult2;
            GPFunction gpfunct = null;

            if (result.Status == esriJobStatus.esriJobSucceeded)
            {
                System.Diagnostics.Debug.WriteLine(result.Process.ToolName.DisplayName + " completed");

                if (_gpfunctions.Count > 0)
                {
                    try
                    {
                        gpfunct = _gpfunctions.Dequeue();

                        _gp.OverwriteOutput = true;  //gpfunct.OverwriteOutput;
                        _gp.AddOutputsToMap = gpfunct.AddtoMap;


                        if (gpfunct.Environments != null)
                        {
                            foreach (KeyValuePair<string, object> kvp in gpfunct.Environments)
                            {
                                _gp.SetEnvironmentValue(kvp.Key, kvp.Value);
                            }
                        }

                        _gp.ExecuteAsync(gpfunct.ToolName, gpfunct.ToolParams);                   //throws exception here

                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine("Error in ToolExecuted");
                        System.Diagnostics.Debug.WriteLine(ex.Message);
                    }
                }
            }
            else
            {
                System.Diagnostics.Debug.WriteLine(result.Process.ToolName.DisplayName + " did something else");

                IGPMessages msgs = result.GetResultMessages();
                for (int i = 0; i < result.MessageCount; i++)
                {
                    IGPMessage msg = (IGPMessage)msgs.GetMessage(i);
                    System.Diagnostics.Debug.WriteLine(msg.Description);
                }
            }

        }


If I click on the button on my form after the Exception occurs it will write my debug statements to the Output panel 2x.

Anyone have an idea what I'm doing wrong & why it seems to be executing the ToolExecuted handler 2x??

Thanks,

Terry
0 Kudos
1 Reply
TerryGiles
Occasional Contributor III
The custom tool works fine if it's the 1st and only tool in the queue, but not if I have to run CopyRaster before hand to make a Tiff to pass to it.

I ended up switching to a synchronous pattern instead, that seems to work regardless of which tools are in my queue.  Not my preferred solution but it'll work for now..


        internal void RunTool(Queue<GPFunction> GPFuncs)
        {
            //Runs a TauDEM GP tool.  Input GPFunction queue can also contain conversion & clean up GP tasks
            //since TauDEM only reads/writes UnCompressed TIFFs

            try
            {
                _gp.AddToolbox(_strTauDEM + "TauDEM5Arc\\TauDEM Tools.tbx");

                foreach (GPFunction gpfunct in GPFuncs)
                {
                    _gp.OverwriteOutput = true; // gpfunct.OverwriteOutput;
                    _gp.AddOutputsToMap = gpfunct.AddtoMap;

                    if (gpfunct.Environments != null)
                    {
                        foreach (KeyValuePair<string, object> kvp in gpfunct.Environments)
                        {
                            _gp.SetEnvironmentValue(kvp.Key, kvp.Value);
                        }
                    }
                    _gp.Execute(gpfunct.ToolName, gpfunct.ToolParams, null);
                }

            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Error in RunTool");
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
        }
0 Kudos