ArcGIS Pro freezes attempting to connect to SDE

1296
11
03-20-2020 02:12 PM
DavidLaMartina
New Contributor III

We're creating an Arc Pro extension that allows users to create database connections to various file types, including GDB and SDE. Below is the code used to create a Geodatabase object out of an SDE connection. This works most of the time.

However, there is a case when this does not work, and ArcGIS Pro completely freezes up and eventually crashes. If I create a connection in the Catalog to a SQL database, that automatically creates an SDE. We need the SDE to access spatial data, so we take that SDE file path and use it to create a Geodatabase object using the code above.

If the "save password" option was not selected when the SQL connection was created, we get the freeze and crash. It makes sense that we would not be able to connect in this case, but wouldn't this crash be considered a bug?

Tags (2)
0 Kudos
11 Replies
Wolf
by Esri Regular Contributor
Esri Regular Contributor

I don't see this in your code, maybe you have this in the calling function, but you must run "new GeoDatabase" from within the context of QueuedTask.Run.  You should see the following text in the help/intellisense string:

"This method must be called on the MCT. Use QueuedTask.Run."  Whenever you see this you have to use QueuedTask.Run.  In terms of code it should look like this:

QueuedTask.Run(() =>
{
  var sdeCon = new DatabaseConnectionFile(new Uri(@"C:\Data\connection.sde"));
  using (Geodatabase sqlServerGeodatabase = new Geodatabase(sdeCon))
  {
    // Use the geodatabase.
  }
});
DavidLaMartina
New Contributor III

Yes, I'm running the code in another thread. It's actually an STA Thread, but I tried changing it to a QueuedTask to no avail.

Part of the reason this seems like a bug is that if it the freeze / crash happens once, and then I open up the same Project and try again, I get an (appropriate) error regarding no credentials. I believe this error is originating from ESRI code.

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

I cannot duplicate your problem.  Using QueuedTask.Run is not optional in an add-in.  I am running the code snippet above using Pro 2.5 without any problems.  What version of Pro are you using and how did you create the .sde connection files (what version of Pro) ?  

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

I tried this in ArcGIS Pro 2.4 and see that the exception is being thrown in the GeoDatabase constructor.  However, i don't get the hanging issue, probably because i used QueuedTask.Run .... 

I will report this to the dev team and check if there's a workaround for this.

Thanks,

Wolf

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

Hi David,

 It turns out the problem (no user/password in the .sde connection file) has been fixed in ArcGIS Pro 2.6.  2.6 is properly prompting for user/password entry when the attempt is made to open the geodatabase.  However, both 2.4 and 2.5 throw an exception (dialog cancelled) instead.  

 Below is a workaround code snippet (2.5) which prompts the user for username/password entry if a username/password has not been support in the .sde connection file.  I use a ProWindow to get the user/password string.  I attached the complete vs 2019 project.

protected override async void OnClick()
{
  try
  {
    // this connection file has no user/password entered
    var sdeCon = new DatabaseConnectionFile(new Uri(@"C:\Users\wlfka\Documents\ArcGIS\Projects\MyTestSDe2\localhost.sde"));
        
    var sdeConProperties = DatabaseClient.GetDatabaseConnectionProperties(sdeCon);
    if (string.IsNullOrEmpty(sdeConProperties.User))
    {
      // prompt for username / password using a ProWindow
      var userPwDlg = new AddInDatabaseConnection();
      Module1.ConnectionString = $@"{sdeConProperties.AuthenticationMode} {sdeConProperties.Instance} {sdeConProperties.Database}";
      userPwDlg.Owner = FrameworkApplication.Current.MainWindow;
      userPwDlg.Closed += (o, e) => { };
      var dlgResult = userPwDlg.ShowDialog();
      if (Module1.HasCredentials == false) return;
      sdeConProperties.User = Module1.UserName;
      sdeConProperties.Password = Module1.Password;
    }

    var hasConnected = await QueuedTask.Run(() =>
        {
          bool bConnected = false;
          try
          {
            using (Geodatabase sqlServerGeodatabase = new Geodatabase(sdeConProperties))
            {
              IReadOnlyList<Definition> fcList = sqlServerGeodatabase.GetDefinitions<FeatureClassDefinition>();
              foreach (var fc in fcList)
                System.Diagnostics.Debug.WriteLine(fc.GetName());
              // Use the geodatabase.
              bConnected = true;
            }
          }
          catch (Exception ex)
          {
            MessageBox.Show($@"Unable to connect: {sdeCon}");
          }
          return bConnected;
        });
    if (hasConnected) MessageBox.Show("Connected");
  }
  catch (Exception ex)
  {
    MessageBox.Show($@"Error: {ex.ToString()}");
  }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

In essence the code parses the connection properties from the .sde file and then prompt for credential input.  It then uses the connection properties to connect and not the .sde file.

ProWindow saves the user/password in the module class and then closes.  i then user the connection properties to open the geodatabase.

DavidLaMartina
New Contributor III

Thank you very much Wolfgang Kaiser‌!

However, another issue has come up. What if the user created the SDE using operating system authentication, rather than explicitly specifying the user and password? Implementing your check, we are now getting false positives for inadequate credentials when this is the case.

I looked at the DatabaseConnectionProperties object in the debugger, and even though the connection was created using OS authentication, the AuthenticationMode property is still DBMS, rather than OSA.

So, if the AuthenticationMode property doesn't change between SDE connections created with user / pass and those created with OS authentication, how can we distinguish between the two? I don't want to tell users using OSA that they have to enter credentials.

EDIT: To be clear, that AuthenticationMode property is ALWAYS DMBS, even when the connection was created with operating system authentication (OSA). Is this another bug that is going to be fixed in 2.6?

I also removed the STA thread portion of my code and wrapped the Geodatabase instantiation in a QueuedTask. Even so, an uncredentialed connection results in an indefinite hang.

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

I duplicated the problem you were seeing.  The property is not showing the correct value, which should be OSA and DBMS.  I tested in the current alpha version of 2.6 and it's a bug in that version as well.  I reported to issue to the GeoDatabase team.  I will give  an update if i hear of a fix or workaround.

Thanks,

Wolf

0 Kudos
RichRuh
Esri Regular Contributor

The bug where the AuthenticationMode property was not returning the correct value will be fixed in Pro 2.6 (summer 2020).

0 Kudos
RichRuh
Esri Regular Contributor

The AuthenticationMode property should now be returning the correct value in Pro 2.6.

0 Kudos