简体   繁体   中英

C# SQLConnection.Open() hangs, with no exception

I am using C# in Visual Studio 2019, with Xamarin.Forms, and SQl in SSMS 2018 and have the below code (where [] is used to replace unneccessary information)

try
{
  using(SqlConnection connection = new SqlConnection())
  {
     connection.ConnectionString = "Server=[ServerName]; Database=[DatabaseName]; User Id= [UserID]; Password=[Password]";

     connection.Open();

     SqlCommand command = new SqlCommand("SELECT * from [TableName]", connection);

     [Does stuff here]
  }
}
catch (Exception ex)
{
  System.Diagnostics.Debug.WriteLine(ex)
}

When I run this, it hangs indefinitely at connection.Open() . Debug mode continues to run and appears to move on from Connection.Open() , but never reaches the next line.

I have attempted this with different versions of the ConnectionString, using different databases and with Trusted_Connection=true instead of specifiying the username and password but they have made no difference. Adding Connection Timeout = 5 to the connectionString has no effect.

I believe it is probably an issue with my settings in SQL but as I am a novice with this I have no idea where to start and the similar forums posts I have checked have been given answers along the lines of Connection Timeout ( Connection.open for hangs indefinitely, no exception is thrown ) or never got answered.

Any advice would be greatly appreciated.

Can you log into SSMS with the credentials that are in the connection string?

Otherwise I've had luck making sure the connection isn't already open or broken first:

if (connection.State == ConnectionState.Closed || connection.State == ConnectionState.Broken)
{
    connection.Open();
}

Can you try code changing line as per below -

connection.ConnectionString = "Data Source=[ServerName]; Initial Catalog=[DatabaseName]; Integrated Security=SSPI;"

A workaround to this problem is to pass in a cancellation token instance as shown below,

public async Task<IEnumerable<Toy>> ShowToybox(CancellationToken t)
{
   // notice I turned this into an async operation. 
   // Reason is to let this operation to find its way out if something happens
    var connString = "Server=xyz; Connection Timeout=250";
    //Timeout might not happen, if that is not the case see below..
    using(SqlConnection connection = new SqlConnection(connString))
    {
        if ( t.IsCancellationRequested) {
            t.ThrowIfCancellationRequested();
        }
       // await query here. To fetch records from the toybox table
       return matches;
     }

Main issue is that you cannot trust connection.State

To get this working, code that consumes this method should expect something might go wrong.

class Program
{
   static void Main()
  {
      var box = new ToxBox(); //it has method shown above
      var s = new CancellationTokenSource();
      s.CancelAfter(400); //it prevents method from hanging
      var task = Task.Run(() = box.ShowToybox(s.Token));
      try
      {
          task.Wait(s.Token);
          var myToys = task.Result();
          Console.WriteLine($"I have {myToys.Count()} toys");
      }
      catch (Exception e)
      {
          Console.WriteLine("Something happened!"); 
      }
      finally
      {
          s.Dispose(); //this is important
      }  
  }
}

See https://docs.microsoft.com/en-us/dotnet/standard/threading/cancellation-in-managed-threads

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM