Unable to create a Task with geometry

441
3
Jump to solution
05-06-2021 02:40 PM
Labels (1)
JS_GilbertAZ
New Contributor II

The solution to this is probably fairly simple but I can't seem to find it anywhere, even in code samples.  I create a task that will pass back a polyline that the task creates.  I declare the polyline locally, but I am unable to assign anything to it, not even able to do "= new polyline();", so what happens is the polyline needs to be created in the QueuedTask, but the line to return that polyline at the end of the function (outside of the QueuedTask) doesn't recognize that so the code fails.  If I put the return statement inside the queuedtask then that error clears up, but the function definition itself has an error that "not all code paths return a value".  I can also only create the polyline within a queuedtask.  Is there a way around this?  It seems like something that would be used pretty often.  Is it just not possible to create a Task with a geometry?  The sample below is what I'm seeing:

async Task<Polyline> CreateLineAtClickPoint(MapPoint m)
{
Polyline pLineClickLoc;
List<MapPoint> LinePoints = new List<MapPoint>();
MapPoint LineStart;
MapPoint LineEnd;
await QueuedTask.Run(() =>
{
togSR = SpatialReferenceBuilder.CreateSpatialReference(2868);
if (StreetQueryIsEW)
{
LineStart = MapPointBuilder.CreateMapPoint(LineXMin, m.Y, togSR);
LineEnd = MapPointBuilder.CreateMapPoint(LineXMax, m.Y, togSR);
}
else
{
LineStart = MapPointBuilder.CreateMapPoint(m.X, LineYMin, togSR);
LineEnd = MapPointBuilder.CreateMapPoint(m.X, LineYMax, togSR);
}
LinePoints.Add(LineStart);
LinePoints.Add(LineEnd);
pLineClickLoc = PolylineBuilder.CreatePolyline(LinePoints);
});
return pLineClickLoc;  //has error "unassigned local variable"
}

I have created tasks with mappoints, like below, but I had to "fudge in" a value to assign the point, like in the sample below, but I can't do that with the polyline.  I don't really like doing that with the mappoint either, it seems rather sloppy (but it does work).

async Task<MapPoint> UnprojectCoordinates(MapPoint p)
{
MapPoint up = MapPointBuilder.CreateMapPoint(0, 0);  //just assign 0,0 to the point to get started, avoid error
await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
togSR = SpatialReferenceBuilder.CreateSpatialReference(2868);
SpatialReference srWGS84 = SpatialReferenceBuilder.CreateSpatialReference(4326);
ProjectionTransformation trTOG2WGS84 = ProjectionTransformation.Create(togSR, srWGS84);
up = GeometryEngine.Instance.ProjectEx(p, trTOG2WGS84) as MapPoint;
});
return up;
}

If there's anything that I can do to resolve this, thank you in advance for assisting me.

Jeff

 

0 Kudos
1 Solution

Accepted Solutions
John_Jones
New Contributor III

Alternatively you could have your work done on the background thread return the result explicitly.  Something like this...

Task<Polyline> CreateLineAtClickPoint(MapPoint m)
{
return QueuedTask.Run(() =>
{
List<MapPoint> LinePoints = new List<MapPoint>();
MapPoint LineStart;
MapPoint LineEnd;
togSR = SpatialReferenceBuilder.CreateSpatialReference(2868);
if (StreetQueryIsEW)
{
LineStart = MapPointBuilder.CreateMapPoint(LineXMin, m.Y, togSR);
LineEnd = MapPointBuilder.CreateMapPoint(LineXMax, m.Y, togSR);
}
else
{
LineStart = MapPointBuilder.CreateMapPoint(m.X, LineYMin, togSR);
LineEnd = MapPointBuilder.CreateMapPoint(m.X, LineYMax, togSR);
}
LinePoints.Add(LineStart);
LinePoints.Add(LineEnd);
return PolylineBuilder.CreatePolyline(LinePoints);
});
}

 

View solution in original post

3 Replies
John_Jones
New Contributor III

I believe you should just initialize pLineClickLoc to null.  While your task (run on the background thread by QueuedTask.Run) will set it to a valid value, the compiler has a hard time proving that to be the case so it looks suspiciously (to the compiler) that you are accessing a local variable that may not have been initialized.  While C# members are initialized to null local variables are not.

0 Kudos
John_Jones
New Contributor III

Alternatively you could have your work done on the background thread return the result explicitly.  Something like this...

Task<Polyline> CreateLineAtClickPoint(MapPoint m)
{
return QueuedTask.Run(() =>
{
List<MapPoint> LinePoints = new List<MapPoint>();
MapPoint LineStart;
MapPoint LineEnd;
togSR = SpatialReferenceBuilder.CreateSpatialReference(2868);
if (StreetQueryIsEW)
{
LineStart = MapPointBuilder.CreateMapPoint(LineXMin, m.Y, togSR);
LineEnd = MapPointBuilder.CreateMapPoint(LineXMax, m.Y, togSR);
}
else
{
LineStart = MapPointBuilder.CreateMapPoint(m.X, LineYMin, togSR);
LineEnd = MapPointBuilder.CreateMapPoint(m.X, LineYMax, togSR);
}
LinePoints.Add(LineStart);
LinePoints.Add(LineEnd);
return PolylineBuilder.CreatePolyline(LinePoints);
});
}

 

JS_GilbertAZ
New Contributor II

Thanks John!  I didn't realize that I could assign the polyline to null, but now I can see how the compiler "thinks" it has been assigned.

I tried the second suggestion as well, it solves what I needed to do.

Thanks again,

Jeff

 

0 Kudos