AccessViolationException - LocalRouteTask on the same geodatabase file

3237
3
07-12-2015 11:29 PM
LinaYap1
New Contributor II

I am using ArcGIS Runtime .NET 10.2.5, and investigating the behaviour of running multiple analysis on different LocalRouteTask instances.

However, either following behaviour will occur frequently:

- exception "AccessViolationException" was thrown (based on the code below) and will kill my test application

- NetworkAnalystException was thrown but could be caught. Subsequent execution on route analysis has no issue.

Note: the following codes were just for reference, as it is supposed to measure time taken to complete 2 analysis on different LocalRouteTask instances. After line X was executed, then then above behaviours will occur.

I am speculating that if more than one LocalRouteTask references the same .geodatabase, and calling SolveAsync() on both tasks simultaneously will cause some issues like above?

...

public async void ButtonClick(object sender, EventArgs e)

{

     LocalRouteTask routeTask1 = new LocalRouteTask(Constants.NetworkDB);

     RouteParameters param1 = await routeTask1.GetDefaultTaskParameters();

     LocalRouteTask routeTask2 = new LocalRouteTask(Constants.NetworkDB);

     RouteParameters param2 = await routeTask2.GetDefaultTaskParameters();

     Task t1 = Task.Run(()=> SolveRoute(routeTask1, param1);    

     Task t2 = Task.Run(()=> SolveRoute(routeTask2, param2); // line X

     await t1;

     await t2;

}

public async Task SolveRoute(LocalRouteTask task, RouteParameters param)
{

     await task.SolveAsync(param);

}

Tags (1)
0 Kudos
3 Replies
AnttiKajanus1
Occasional Contributor III

Hi Lina,

I tried to run similar case with 10.2.5 and 10.2.6 but I cannot reproduce the issue. Can you send me a small reproducer to check? You can mail it to akajanus () esri.com.

Cheers

0 Kudos
nakulmanocha
Esri Regular Contributor

Could you please test with 10.2.6 which got just released

https://developers.arcgis.com/net/

if possible please provide a simple repro case here.

Thanks.

0 Kudos
LinaYap1
New Contributor II

Hi, right now I am using 10.2.6 to test... The code segment below (ORIGINAL) also produces the AccessViolationException with 10.2.6 occasionally.

  • Note if the Exception do not happen on the first run, restart application again. I seem to get this exception 1 out of 5 times.

I made some slight changes to the original code, and AccessViolationException seems to be eliminated. I have not done rigorous testing yet to ensure that this behave safely...:

Changes (See UPDATED code segment below):

- Remove LocalRouteTask instance creation in Parallel() method.

- Create LocalRouteTask instance in the SolveAsync() method, and then use that instance to solve route problem.

This somehow seems eliminates the AccessViolationException.

  • NetworkAnalystException is still thrown sometimes on the first run, with message "Cannot solve".

I am guessing that in the original code segment, LocalRouteTask was created in another thread (eg. ThreadID = 10), and then was used to solve routing problem in other threads (eg. ThreadID=15 and ThreadID=16) which might cause the Exception to happen(?). Just my guess - would be nice to know exactly why AccessViolationException happens.

  • The following will also cause the AccessViolationException to occur. Don't really suppose it is thread issue...

void Parallel()
{

...

  LocalRouteTask task1 = new LocalRouteTask(Constants.NetworkDB);

  RouteParameters param1 = await GetParam(...);

  LocalRouteTask task2 = new LocalRouteTask(Constants.NetworkDB);

  RouteParameters param2 = await GetParam(...);

...

  for (int i = 0; i < 5; i++)

  {

  Task t1 = task1.SolveAsync(param1);

  Task t2 = task2.SolveAsync(param2);

  await t1;

  await t2;

  }

...

}

ORIGINAL---

private async Task<RouteParameters> GetParam(LocalRouteTask task, string dirStyle, bool includeBarrier)

{

  RouteParameters routeParams = await task.GetDefaultParametersAsync();

  routeParams.FindBestSequence = false;

  routeParams.PreserveFirstStop = false;

  routeParams.PreserveLastStop = false;

  routeParams.OutputLines = OutputLine.TrueShapeWithMeasure;

  routeParams.DirectionsLengthUnit = LinearUnits.Meters;

  routeParams.DirectionsStyleName = dirStyle;

  routeParams.DirectionsLanguage = new CultureInfo("en-US"); ;

  routeParams.ReturnStops = true;

  routeParams.ReturnRoutes = true;

  routeParams.ReturnDirections = true;

  routeParams.ReturnPointBarriers = true;

  routeParams.ReturnPolygonBarriers = true;

  routeParams.ReturnPolylineBarriers = true;

  routeParams.IgnoreInvalidLocations = false;

  return routeParams;

}

private async void Parallel(object sender, RoutedEventArgs e)

{

  try

  {

  MapPoint mp0 = new MapPoint(11541840.7711455, 146578.730235322, SpatialReference.Create(102100));

  MapPoint mp1 = new MapPoint(11570869.2480698, 146689.314909319, SpatialReference.Create(102100));

  List<Graphic> stops = new List<Graphic>() { new Graphic(mp0), new Graphic(mp1) };

  LocalRouteTask task1 = new LocalRouteTask(Constants.NetworkDB);

  RouteParameters param1 = await GetParam(task1, Constants.NADesktop, false);

  param1.SetStops(stops);

  LocalRouteTask task2 = new LocalRouteTask(Constants.NetworkDB);

  RouteParameters param2 = await GetParam(task2, Constants.NADesktop, false);

  param2.SetStops(stops);

  Stopwatch stopwatch = new Stopwatch();

  stopwatch.Start();

  for (int i = 0; i < 5; i++)

  {

  Task t1 = Task.Run(async () => { await SolveRouteAsync(1, stopwatch, task1, param1); });

  Task t2 = Task.Run(async () => { await SolveRouteAsync(2, stopwatch, task2, param2); });

  await t1;

  await t2;

  }

  //stopwatch.Stop();

  Console.WriteLine("Parallel timing: " + stopwatch.ElapsedMilliseconds);

  task1.Dispose();

  task2.Dispose();

  }

  catch (AggregateException ex)

  {

  Console.WriteLine(ex.ToString());

  }

  catch (Exception ex)

  {

  Console.WriteLine(ex.ToString());

  }

}

private async Task SolveRouteAsync(int id, Stopwatch stopwatch, LocalRouteTask task, RouteParameters param)

{

  Console.WriteLine("elapsed run {0}: {1} ", id, stopwatch.ElapsedMilliseconds);

  RouteResult t1 = await task.SolveAsync(param).ConfigureAwait(false);

}

ORIGINAL END---

UPDATED---

private async void Parallel(object sender, RoutedEventArgs e)

{

  try

  {

  MapPoint mp0 = new MapPoint(11541840.7711455, 146578.730235322, SpatialReference.Create(102100));

  MapPoint mp1 = new MapPoint(11570869.2480698, 146689.314909319, SpatialReference.Create(102100));

  List<Graphic> stops = new List<Graphic>() { new Graphic(mp0), new Graphic(mp1) };

  Stopwatch stopwatch = new Stopwatch();

  stopwatch.Start();

  for (int i = 0; i < 5; i++)

  {

  Task t1 = Task.Run(async () => { await SolveRouteAsync(1, stopwatch, stops); });

  Task t2 = Task.Run(async () => { await SolveRouteAsync(2, stopwatch, stops); });

  await t1;

  await t2;

  }

  //stopwatch.Stop();

  Console.WriteLine("Parallel timing: " + stopwatch.ElapsedMilliseconds);

  }

  catch (AggregateException ex)

  {

  Console.WriteLine(ex.ToString());

  }

  catch (Exception ex)

  {

  Console.WriteLine(ex.ToString());

  }

}

private async Task SolveRouteAsync(int id, Stopwatch stopwatch, List<Graphic> stops)

{

  LocalRouteTask task = new LocalRouteTask(Constants.NetworkDB);

  RouteParameters param = await GetParam(task, Constants.NADesktop, false);

  param.SetStops(stops);

  Console.WriteLine("elapsed run {0}: {1} ", id, stopwatch.ElapsedMilliseconds);

  RouteResult t1 = await task.SolveAsync(param).ConfigureAwait(false);

  task.Dispose();

}

0 Kudos