How to use QueuedTask.Run()

5779
4
Jump to solution
05-13-2020 11:32 AM
Vidar
by
Occasional Contributor II

Hi,

I'm a bit confused about how to properly use QueuedTask.Run().

If I have two or more API calls that require to be run on the MCT - do I wrap each of those calls individually into a QueuedTask.Run()? Or can I wrap all the calls under one giant QueuedTask.Run()?  I am puzzled more, if I am to also allowed to wrap my own business logic under the QueuedTask.Run along with actual Pro SDK API calls that absolutely MUST be run under QueuedTask.Run(). Is this a bit of no no?

So lets look at some code:

if (map != null && isOverwriteMaps)

  {

    CloseMap(map.Name);

    await CleanMap(map);

  }

else

{

  await QueuedTask.Run(() =>

  {

    map = MapFactory.Instance.CreateMap(mapName, MapType.Map, MapViewingMode.Map, Basemap.None);

  });

  await QueuedTask.Run(() =>

  {

    map.SetSpatialReference(SpatialReferenceBuilder.CreateSpatialReference(4326));

  });

}

So I am using QueuedTask.Run three times - can I just use it once and wrap the whole thing or I right to use it for each individual case?  

I think you have to be careful to run big blocks of code within QueuedTask.Run in case there is a call that requires it to be run on the GUI thread. Am I right in my thinking here?

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
Wolf
by Esri Regular Contributor
Esri Regular Contributor

That's correct.  Things like edit operations, geometry manipulations, etc. that don't require user interaction you would always run from within the context of QueuedTask.Run - first to keep the UI responsive, but also because most of these API operations require that they run on the MCT.  If you have to interact with user input or you call an asynchronous 'Async' method (like for example Project.SaveAsync) you can do this from the UI thread.  If you would write your own asynchronous function like let's say you write your own SaveProjectAsync method, then you would use QueuedTask.Run in the implementation of that method - like it was demonstrated in the video listed above.

View solution in original post

4 Replies
Wolf
by Esri Regular Contributor
Esri Regular Contributor

You can read about using QueuedTask here:  https://github.com/Esri/arcgis-pro-sdk/wiki/ProConcepts-Framework#using-queuedtask.  Calling QueuedTask.Run multiple times in a row will only hurt performance.  But in essence QueuedTask is used to encapsulate your business logic processing in order to keep the UI responsive.  Also this YouTube video covers the basics starting from 26 minutes into the presentation:  ArcGIS Pro SDK for .NET: Beginning Pro Customization and Extensibility - YouTube 

0 Kudos
Vidar
by
Occasional Contributor II

Hey thanks Wolf. I have been over those resources - so I was just checking my thinking here. So basically I want to keep down the amount of times I make an explicit call to QueuedTask.Run() - and essentially wrap all my code into it including any Pro API calls that need to be run on the MCT thread? (but leaving out calls specific to the GUI as they have to be run on the GUI thread).

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

That's correct.  Things like edit operations, geometry manipulations, etc. that don't require user interaction you would always run from within the context of QueuedTask.Run - first to keep the UI responsive, but also because most of these API operations require that they run on the MCT.  If you have to interact with user input or you call an asynchronous 'Async' method (like for example Project.SaveAsync) you can do this from the UI thread.  If you would write your own asynchronous function like let's say you write your own SaveProjectAsync method, then you would use QueuedTask.Run in the implementation of that method - like it was demonstrated in the video listed above.

RichardDaniels
Occasional Contributor III

What is the best way to do something like this? I need to wait until a layout templated is loaded before updating some of its elements.

*this example will not run since we can't return a Task<> with this call.

//add the layout to the project and wait for import to complete

Task t = await QueuedTask.Run<Task>(() => Project.Current.ImportItem(theItem, true));
t.Wait;

0 Kudos