How to wait for new Geodatabase()

216
5
Jump to solution
2 weeks ago
BarbaraSchneider2
Occasional Contributor III

I change the data source of a stereo map programmatically (see here ). I dissassembled the following line of code

 

var workspaceConnectionString = new Geodatabase(fileGdbConnPath).GetConnectionString();

 

to

 

Geodatabase gdb = new Geodatabase(fileGdbConnPath);
string workspaceConnectionString = gdb.GetConnectionString();

 

to better explain the problem.  Creating the gdb has to be run on the MCT thread:

 

Geodatabase gdb = new Geodatabase(fileGdbConnPath);

 

Ok, I did this (see code in above link). However, when I run this line of code, it is running away on a thread, but  I want to await it. How can I achieve this? This is not supported by the compiler:

 

Geodatabase gdb = await new Geodatabase(fileGdbConnPath);

 

Thanks,
Barbara

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
CharlesMacleod
Esri Regular Contributor

ok, so this might take a cpl of back and forths - can u remove the "return Task.CompletedTask" bit - I am also thinking it wont compile with that....also, perhaps there is some more copy/paste "baggage" here?.....can this...

 var fileGdbConnPath = new FileGeodatabaseConnectionPath(new Uri(gdbPath, UriKind.Absolute));
 Geodatabase gdb = new Geodatabase(fileGdbConnPath);
 string workspaceConnectionString = gdb.GetConnectionString();				

  using (var fileGdb = new Geodatabase(fileGdbConnPath)){

be changed to this

  var fileGdbConnPath = new FileGeodatabaseConnectionPath(
                             new Uri(gdbPath, UriKind.Absolute));
  using (var fileGdb = new Geodatabase(fileGdbConnPath))
  {
    string workspaceConnectionString = fileGdb.GetConnectionString();
    ...
  }

 

and then let's go from there.

View solution in original post

5 Replies
CharlesMacleod
Esri Regular Contributor

it is clear from your post that you are experiencing some kind of asynchronicity that u are trying to counter act with "await".   "await QueuedTask.Run(() => { .... code here  })" is the correct pattern to "a wait" the execution of something that is running on the MCT....so, given that u already know this, can u explain what the behavior is you are seeing vs what you are/were trying to accomplish? Please put all the code in question here and not just the new Geodatabase one liner.

0 Kudos
Aashis
by Esri Contributor
Esri Contributor

The geodatabase-related operations are inside the ArcGIS Core.* namespace and tend to be very fine-grained. These methods are synchronous to reduce the overhead associated with scheduling and thread context switches. Those fine-grained synchronous methods must be called within a QueuedTask.

QueuedTask.Run(() =>
{
Geodatabase gbd = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri("")));
});

 

For Pro's threading details, refer to https://github.com/esri/arcgis-pro-sdk/wiki/ProConcepts-Framework#working-with-multithreading-in-arc...

0 Kudos
BarbaraSchneider2
Occasional Contributor III

Sorry, my post was too short. The entire code to programmatically load stereo images into a stereo map is the following:

await QueuedTask.Run(() =>
{
	CIMMap cimMap = stereoMap.GetDefinition();
	var stereoProps = cimMap.StereoProperties;

	WorkspaceFactory workspaceFactory = WorkspaceFactory.FileGDB;
	var fileGdbConnPath = new FileGeodatabaseConnectionPath(new Uri(gdbPath, UriKind.Absolute));
    Geodatabase gdb = new Geodatabase(fileGdbConnPath);
    string workspaceConnectionString = gdb.GetConnectionString();				

	using (var fileGdb = new Geodatabase(fileGdbConnPath))
    {
		MosaicDataset mosaicDataset = fileGdb.OpenDataset<MosaicDataset>(mosaicName);
		CIMStandardDataConnection mosaicDataConnection = new CIMStandardDataConnection()
		{
			WorkspaceConnectionString = workspaceConnectionString,
			WorkspaceFactory = workspaceFactory,
			Dataset = mosaicName,
			DatasetType = esriDatasetType.esriDTMosaicDataset
		};
		var (leftImageID, rightImageID) = GetStereoImages(mosaicDataset);

		stereoProps.SourceType = StereoSourceType.StereoModelCollection;
		stereoProps.StereoModelCollection = mosaicDataConnection;
		stereoProps.LeftImageID = leftImageID;
		stereoProps.RightImageID = rightImageID;

		cimMap.StereoProperties = stereoProps;
		stereoMap.SetDefinition(cimMap);
	}
	return Task.CompletedTask;
});

Even though I put the entire code within a queued task and I await for it (await QueuedTask.Run(() =>), the code runs away when I call Geodatabase gdb = new Geodatabase(fileGdbConnPath), and I 'm not able to wait until the stereo images are loaded.

I have to wait until the images are loaded before I can load layers to the stereo map. Alternatively, I could wait for the images to be loaded in the method OnDrawComplete(MapViewEventArgs args) in my module. This would be a workaround.

Thanks for your help anyway.

0 Kudos
CharlesMacleod
Esri Regular Contributor

ok, so this might take a cpl of back and forths - can u remove the "return Task.CompletedTask" bit - I am also thinking it wont compile with that....also, perhaps there is some more copy/paste "baggage" here?.....can this...

 var fileGdbConnPath = new FileGeodatabaseConnectionPath(new Uri(gdbPath, UriKind.Absolute));
 Geodatabase gdb = new Geodatabase(fileGdbConnPath);
 string workspaceConnectionString = gdb.GetConnectionString();				

  using (var fileGdb = new Geodatabase(fileGdbConnPath)){

be changed to this

  var fileGdbConnPath = new FileGeodatabaseConnectionPath(
                             new Uri(gdbPath, UriKind.Absolute));
  using (var fileGdb = new Geodatabase(fileGdbConnPath))
  {
    string workspaceConnectionString = fileGdb.GetConnectionString();
    ...
  }

 

and then let's go from there.

BarbaraSchneider2
Occasional Contributor III

Thank you, Charles. In my code sample above, I created the Geodatabase twice, what is wrong. The correct code to load stereo images into a stereo map is:

await QueuedTask.Run(() =>
{
	CIMMap cimMap = stereoMap.GetDefinition();
	var stereoProps = cimMap.StereoProperties;

	WorkspaceFactory workspaceFactory = WorkspaceFactory.FileGDB;
	var fileGdbConnPath = new FileGeodatabaseConnectionPath(new Uri(gdbPath, UriKind.Absolute));

	using (var fileGdb = new Geodatabase(fileGdbConnPath))
	{
		string workspaceConnectionString = fileGdb.GetConnectionString();
		MosaicDataset mosaicDataset = fileGdb.OpenDataset<MosaicDataset>(mosaicName);
		CIMStandardDataConnection mosaicDataConnection = new CIMStandardDataConnection()
		{
			WorkspaceConnectionString = workspaceConnectionString,
			WorkspaceFactory = workspaceFactory,
			Dataset = mosaicName,
			DatasetType = esriDatasetType.esriDTMosaicDataset
		};
		var (leftImageID, rightImageID) = GetStereoImages(mosaicDataset);

		stereoProps.SourceType = StereoSourceType.StereoModelCollection;
		stereoProps.StereoModelCollection = mosaicDataConnection;
		stereoProps.LeftImageID = leftImageID;
		stereoProps.RightImageID = rightImageID;

		cimMap.StereoProperties = stereoProps;
		stereoMap.SetDefinition(cimMap);
	}
	return Task.CompletedTask;
});

And the code doesn't run away any more when I call Geodatabase gdb = new Geodatabase(fileGdbConnPath)! I also suspect that there was a problem with the ArcGIS Pro 3.3 Beta Version.

0 Kudos