I am using ArcGIS Engine with background 64bit and calling GP tools using the ExecuteAsync event. I want to continue processing the results of the GP tool execution after it finishes. Following the official example of gp.ToolExecuted to monitor the execution status of the GP tool, I noticed that the event within gp.ToolExecuted is triggered only after the main function completes. How can I modify my code to handle the GP tool's results immediately after execution, without waiting for the main function to finish?
private async void btnRunGP_Click(object sender, EventArgs e)
{
try
{
#region tidy up any previous gp runs
//Clear the ListView control
listView1.Items.Clear();
//Remove any result layers present in the map
IMapLayers mapLayers = axMapControl1.Map as IMapLayers;
foreach (IFeatureLayer resultLayer in _resultsList)
{
mapLayers.DeleteLayer(resultLayer);
}
axTOCControl1.Update();
_resultsList.Clear();
_myGPToolsToExecute.Clear();
#endregion
ESRI.ArcGIS.AnalysisTools.Buffer bufferTool = new ESRI.ArcGIS.AnalysisTools.Buffer();
bufferTool.in_features = _layersDict["Cities"];
bufferTool.buffer_distance_or_field = txtBufferDistance.Text + " Miles";
bufferTool.out_feature_class = "city_buffer.shp";
ESRI.ArcGIS.AnalysisTools.Clip clipTool = new ESRI.ArcGIS.AnalysisTools.Clip();
clipTool.in_features = _layersDict["ZipCodes"];
clipTool.clip_features = bufferTool.out_feature_class;
clipTool.out_feature_class = "city_buffer_clip.shp";
_myGPToolsToExecute.Enqueue(bufferTool);
_myGPToolsToExecute.Enqueue(clipTool);
_gp.ExecuteAsync(_myGPToolsToExecute.Dequeue());
//I want to do something after executeAsync,but I dont want to put them in ToolExecuted
MessageBox.show("finish")
}
catch (Exception ex)
{
listView1.Items.Add(new ListViewItem(new string[2] { "N/A", ex.Message }, "error"));
}
}
void _gp_ToolExecuted(object sender, ToolExecutedEventArgs e)
{
IGeoProcessorResult2 gpResult = (IGeoProcessorResult2)e.GPResult;
try
{
//The first GP tool has completed, if it was successful process the others
if (gpResult.Status == esriJobStatus.esriJobSucceeded)
{
listView1.Items.Add(new ListViewItem(new string[2] { "ToolExecuted", gpResult.Process.Tool.Name }, "success"));
//Execute next tool in the queue
if (_myGPToolsToExecute.Count > 0)
{
_gp.ExecuteAsync(_myGPToolsToExecute.Dequeue());
}
//If last tool has executed add the output layer to the map
else
{
IFeatureClass resultFClass = _gp.Open(gpResult.ReturnValue) as IFeatureClass;
IFeatureLayer resultLayer = new FeatureLayerClass();
resultLayer.FeatureClass = resultFClass;
resultLayer.Name = resultFClass.AliasName;
//Add the result to the map
axMapControl1.AddLayer((ILayer)resultLayer, 2);
axTOCControl1.Update();
//add the result layer to the List of result layers
_resultsList.Add(resultLayer);
}
}
//If the GP process failed, do not try to process any more tools in the queue
else if (gpResult.Status == esriJobStatus.esriJobFailed)
{
//The actual GP error message will be output by the MessagesCreated event handler
listView1.Items.Add(new ListViewItem(new string[2] { "ToolExecuted", gpResult.Process.Tool.Name + " failed, any remaining processes will not be executed." }, "error"));
//Empty the queue
_myGPToolsToExecute.Clear();
}
}
catch (Exception ex)
{
listView1.Items.Add(new ListViewItem(new string[2] { "ToolExecuted", ex.Message }, "error"));
}
}
I also tried adding a while loop to block the GP tool execution until it completes, but the gp.Execute function didn't execute at all—it kept looping.
What should I do to handle this situation?
_gp.ExecuteAsync(_myGPToolsToExecute.Dequeue());
while(!isDone){}
//I want to do something after executeAsync,but I dont want to put them in ToolExecuted
MessageBox.show("finish")