C# SQLConnection.Open() 挂起,无一例外

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

我在 Visual Studio 2019 中使用 C#,在 SSMS 2018 中使用 Xamarin.Forms 和 SQl,并具有以下代码(其中 [] 用于替换不必要的信息)

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)
}

当我 运行 这个时,它会无限期地挂在 connection.Open()。调试模式继续到 运行,似乎从 Connection.Open() 继续,但从未到达下一行。

我尝试过使用不同版本的 ConnectionString、使用不同的数据库并使用 Trusted_Connection=true 而不是指定用户名和密码,但它们没有任何区别。将 Connection Timeout = 5 添加到 connectionString 没有任何效果。

我认为这可能是我在 SQL 中的设置的问题,但由于我是这方面的新手,我不知道从哪里开始,我检查过的类似论坛帖子已经给出了答案Connection Timeout (Connection.open for hangs indefinitely, no exception is thrown) 行或从未得到答复。

如有任何建议,我们将不胜感激。

您可以使用连接字符串中的凭据登录 SSMS 吗?

否则我很幸运确保连接尚未打开或断开:

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

你能尝试按照下面的代码更改行吗 -

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

此问题的解决方法是传入一个取消令牌实例,如下所示,

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;
     }

主要问题是您不能信任connection.State

要使其正常工作,使用此方法的代码应该预料到可能会出错。

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
      }  
  }
}

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