CoreHost in AutoCAD

311
7
09-15-2021 04:59 PM
JimmyBowden
Occasional Contributor

Behavior described below was tested in ArcGIS Pro 2.6.3 and 2.8.2 and works the same in both.  Using .net framework 4.8.

I have this code snippet using the ArcGIS Pro SDK CoreHost that is run through AutoCAD 2021 using the netload command.  This first example connects to an Enterprise Geodatabase using an sde connection to get a list of versions and works every time the command is executed.  This is part of a bigger application that reads data from an SDE Version (selected by the user) and creates entities in the AutoCAD drawing.  

[STAThread]
//AutoCAD .net runtime command
[CommandMethod("AGTEST")]
public void Execute()
{    
    Host.Initialize();
    var sdeconn = new DatabaseConnectionFile(new Uri("pathto.sde file"));
    var gdb = new Geodatabase(sdeconn);
    if (gdb.IsVersioningSupported())
    {
        var versionm = gdb.GetVersionManager();
        var versions = versionm.GetVersionNames().OrderBy(p => p).ToList();
    }
}

I'm currently attempting to move to a Utility Network and updating the code to use  ServiceConnectionProperties to instantiate the GeoDatabase.  

[STAThread]
//AutoCAD .net runtime command
[CommandMethod("AGTEST")]
public void Execute()
{
    Host.Initialize();
    var scp = new ServiceConnectionProperties(new Uri("https://myportal.mydomain.com/arcgis/rest/services/UN/Water_Distribution_Utility_Network/FeatureServer"));
    var gdb = new Geodatabase(scp);
    if (gdb.IsVersioningSupported())
    {
        var versionm = gdb.GetVersionManager();
        var versions = versionm.GetVersionNames().OrderBy(p => p).ToList();                                
    }           
}
The first time this code is ran it works as expected.  Sometimes even subsequent executions work but eventually an exception will be thrown on line 12. The error reported is ArcGIS.Core.Data.GeodatabaseGeneralException HResult=0x80131500 Message=The application is not licensed to edit this type of data.
Since it's service request I'm able to see what is happening with Fiddler and at some point the token stops being supplied in the requests and this is what triggers the error. 
I would appreciate any advice on how to make this work.
 
Thanks, Jimmy
0 Kudos
7 Replies
RichRuh
Esri Regular Contributor

Jimmy, 

I'm not familiar with this AutoCAD environment, so this is pure speculation.

Is it possible that your code is running on multiple threads?  It works mostly, except when a second thread tries to execute the code and that second thread doesn't have the licensing token?

One thing I would try is to wrap your geodatabase calls with QueuedWorker. This class works like QueuedTask inside a Pro add-in, but is designed for CoreHost apps.

I hope this helps,

--Rich

0 Kudos
JimmyBowden
Occasional Contributor

Thanks for the reply @RichRuh.  Wrapping the code with QueuedWorker didn't help, same result.  For now we can have users close AutoCAD between commands that need ArcGIS data, which is not ideal but at least it will get what we need into AutoCAD.  It's unfortunate since it has been working really well using a direct sde connection. If I get more time in the future I will try to redesign or maybe ArcGIS for AutoCAD will get to where it can read branch versions.

0 Kudos
RichRuh
Esri Regular Contributor

One more thing to try if you're still willing.  What happens if you call ArcGISSignOn.IsSignedOn prior to the call to VersionManager.GetVersionNames()?  I'm guessing it returns True in those cases where GetVersionNames succeeds, and returns False in those cases where it fails, but it would be good to know for sure. 

0 Kudos
JimmyBowden
Occasional Contributor

I tried IsSignedOn and it does not return false it actually throws the following exception:

ArcGIS.Core.SystemCore.SystemCoreException: 'Error HRESULT E_FAIL has been returned from a call to a COM component.'

0 Kudos
RichRuh
Esri Regular Contributor

It still feels like a threading problem to me.  

First, each of these processes is finishing before it executes a second time, right?

Second, have you tried calling Dispose on each of the geodatabase objects (including the version manager, any version objects you create, feature classes, cursors, rows, etc.), or use `using` statements?  If you don't clean them up, it's possible that one thread is creating them and another thread is reusing them (the objects might be cached internally).

Other than that, I'm out of ideas.

 

0 Kudos
JimmyBowden
Occasional Contributor

Yes the process appears to complete each time.

I think you're on to something with the Dispose/Using.  I put the versionmanager into a using block and that helps.  There's still some issues but I suspect there are some other objects that are not in a using or disposed of.  Hopefully once I get them being disposed it will just work.

0 Kudos
CharlesMacleod
Esri Regular Contributor

try locking. assuming autocad is not spinning up multiple instances then_

private static object readonly _lock = new object();

public void Execute()
{
    Host.Initialize();
    lock(_lock) {
      var scp = new ServiceConnectionProperties(new Uri("https://myportal.mydomain.com/arcgis/rest/services/UN/Water_Distribution_Utility_Network/FeatureServer"));
      var gdb = new Geodatabase(scp);
      if (gdb.IsVersioningSupported())
      {
         var versionm = gdb.GetVersionManager();
         var versions = versionm.GetVersionNames().OrderBy(p => p).ToList();                                
      }  
    } 
}

 

if the lock resolves the issue u can remove methods from the scope of the lock until it doesnt work again - at that point u will have found the minimum required scope of the lock.

Note: if autocad _is_ spinning up multiple instances u may need a mutex instead.

 

 

0 Kudos