private void GeoprocessorTask_JobCompleted(object sender, JobInfoEventArgs e) { if (e.JobInfo.JobStatus != esriJobStatus.esriJobSucceeded) { MessageBox.Show("Geoprocessor service failed" ); ProcessingTextBlock.Text = ""; ProcessingTextBlock.Visibility = Visibility.Collapsed; GraphicsLayer graphicsLayer = Map.Layers["Results"] as GraphicsLayer; GraphicsLayer startLayer = Map.Layers["MyGraphicsLayer"] as GraphicsLayer; graphicsLayer.ClearGraphics(); startLayer.ClearGraphics(); this.SpreadModel.IsOpen = !this.SpreadModel.IsOpen; } else { Geoprocessor geoprocessorTask = sender as Geoprocessor; geoprocessorTask.GetResultDataCompleted += (s1, ev1) => { if (ev1.Parameter is GPFeatureRecordSetLayer) { GraphicsLayer graphicsLayer = Map.Layers["Results"] as GraphicsLayer; GPFeatureRecordSetLayer gpLayer = ev1.Parameter as GPFeatureRecordSetLayer; foreach (Graphic graphic in gpLayer.FeatureSet.Features) { graphic.Symbol = LayoutRoot.Resources["MyGreenFillSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol; graphicsLayer.Graphics.Add(graphic); } } if (ev1.Parameter is GPDataFile) { GPDataFile gpdata = ev1.Parameter as GPDataFile; Uri uri = new Uri(gpdata.Url); btndownload.NavigateUri = uri; urltodownload = uri; geoprocessorTask.GetResultDataAsync(e.JobInfo.JobId, "RelativeSpread"); } }; geoprocessorTask.GetResultDataAsync(e.JobInfo.JobId, "Outfile"); } }
Solved! Go to Solution.
gp.getResultData(jobInfo.jobId,"Outfile",downloadFile)
Have you looked at the Samples?
There are several for geoprocessing tasks.
P.S. JavaScript not Java. 🙂
There is only one using asynchronous and it has one result not two. If it was synchronous I would just use result[0].value etc but it is not.
That's not really an issue, you just have to get used to using callbacks to handle async responses. Functions are first-class objects in JavaScript so you define and pass them around, assign them to things (think delegate in C#) including assigning them as a callback handler for an async request.
I assume the sample you're referring to is this one?
I guess the "completeCallback" function is the equivalent of your "GeoprocessorTask_JobCompleted" method and receives a JobInfo object which is the same as your "JobInfoEventArgs".
Then you still make an async call to get the results by calling "getResultData" and you pass a callback to that method the same way that you're assigning an anonymous delegate (using lambda syntax) in C#, in the sample the callback is called "downloadFile". The callback receives an argument of type ParameterValue whereas in C# you're being passed "s1 and ev1".
I'm struggling to see where having 2 or 3 or 'n' tasks makes any difference?
so basically I need to modify the downloadfile to then see if the result is a GPDataFile or other.
Can I enumerate the number of results retrieved so I can then use a 'for' statement to run while I still have results left to be processed?
When I call the first getResultsData specifying the first result I want to retrieve the script stops on completing that request. I then don't get to specify my second result in the getResultsData . How do I get my script to loop back to do another getResultsData?
Yep, pretty much.
Although with your new-found understanding I think it'd be more beneficial for you to write this from scratch step-by-step so you get a really good 'feel' for what happens at each stage, but that's just my opinion 😉
Yep, you can iterate over the results, you could use intrinsic JavaScript looping constructs but you'd probably get more out of the array utilities provided by dojo - have a look here:- dojo-base-array
Not 100% sure what you mean? Let's have a look at the code.
function completeCallback(jobInfo){ if (jobInfo.jobStatus !== "esriJobFailed") { gp.getResultData(jobInfo.jobId,"RelativeSpread",outputgraphic); gp.getResultData(jobInfo.jobId,"Outfile",downloadFile) } } function statusCallback(jobInfo){ var status = jobInfo.jobStatus; if (status === "esriJobFailed") { alert(status); esri.hide(loading); } else if (status === "esriJobSucceeded") { esri.hide(loading); } } function downloadFile(outputFile){ var theurl = outputFile.value.url; window.location = theurl; } function outputgraphic(resultGraphic){ var polySymbol = new esri.symbol.SimpleFillSymbol(); polySymbol.setOutline(new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 0, 0.5]), 1)); polySymbol.setColor(new dojo.Color([255, 127, 0, 0.7])); var features = resultGraphic.value.features; for (var f = 0, fl = features.length; f < fl; f++) { var feature = features; if (f == 0) { var polySymbolRed = new esri.symbol.SimpleFillSymbol(); polySymbolRed.setOutline(new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 0, 0.5]), 1)); polySymbolRed.setColor(new dojo.Color([56, 168, 0, 0.5])); feature.setSymbol(polySymbolRed); } else if (f == 1) { var polySymbolGreen = new esri.symbol.SimpleFillSymbol(); polySymbolGreen.setOutline(new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 0, 0.5]), 1)); polySymbolGreen.setColor(new dojo.Color([139, 209, 0, 0.5])); feature.setSymbol(polySymbolGreen); } else if (f == 2) { var polySymbolBlue = new esri.symbol.SimpleFillSymbol(); polySymbolBlue.setOutline(new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 0, 0.5]), 1)); polySymbolBlue.setColor(new dojo.Color([255, 255, 0, 0.5])); feature.setSymbol(polySymbolBlue); } else if (f == 3) { var polySymbolBlue = new esri.symbol.SimpleFillSymbol(); polySymbolBlue.setOutline(new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 0, 0.5]), 1)); polySymbolBlue.setColor(new dojo.Color([255, 128, 0, 0.5])); feature.setSymbol(polySymbolBlue); } else if (f == 4) { var polySymbolBlue = new esri.symbol.SimpleFillSymbol(); polySymbolBlue.setOutline(new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 0, 0.5]), 1)); polySymbolBlue.setColor(new dojo.Color([255, 0, 0, 0.5])); feature.setSymbol(polySymbolBlue); } map.graphics.add(feature); } }
/ArcGIS/rest/services/APHIS/SpreadModel1/GPServer/APHIS%20Group1/jobs/jbb3326de83dd496fae901188259256d2/results/RelativeSpread?f=json&returnType=data&callback=dojo.io.script.jsonp_dojoIoScript9._jsonpCallback /ArcGIS/rest/services/APHIS/SpreadModel1/GPServer/APHIS%20Group1/jobs/jbb3326de83dd496fae901188259256d2/results/Outfile?f=json&returnType=data&callback=dojo.io.script.jsonp_dojoIoScript10._jsonpCallback
if (jobInfo.jobStatus !== "esriJobFailed") { var def = new dojo.Deferred(); setTimeout(function(){ def.resolve({called: true});}, 1000); gp.getResultData(jobInfo.jobId, "RelativeSpread", outputgraphic) def.then(function(){ gp.getResultData(jobInfo.jobId, "Outfile", downloadFile) })
gp.getResultData(jobInfo.jobId,"RelativeSpread",outputgraphic); gp.getResultData(jobInfo.jobId,"Outfile",downloadFile)
That's kind of losing the benefit of doing async processing i.e. you're now blocking on something before starting something else, if they are independent then there's no need.
FWIW, the first problem I can see is this:gp.getResultData(jobInfo.jobId,"RelativeSpread",outputgraphic); gp.getResultData(jobInfo.jobId,"Outfile",downloadFile)
The completeCallback function will be called twice on separate occasions i.e. once for each task, your code (above) tries to access the results of each task both times! (comment out those two lines and put a breakpoint in then check out what's in the jobInfo argument on each call, this should clarify it for you)
You need to do something like check which task has returned then call the appropriate getResultData for that task, although overall I think you could re-write then whole lot to be more generic/reusable etc.
I really would start this again from scratch and check your understanding of async processing at each stage, once the penny drops you'll find this stuff easy 🙂