当前位置:  开发笔记 > 编程语言 > 正文

为什么在这种情况下会忽略ConnectTimeout?

如何解决《为什么在这种情况下会忽略ConnectTimeout?》经验,为你挑选了1个好方法。

运行此代码时:

static void Main(string[] args)
{
    SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder();
    csb.DataSource = @"8.8.8.8"; // some inaccessible ip address
    csb.InitialCatalog = "Tempdb";
    csb.IntegratedSecurity = true;
    csb.ConnectTimeout = 1;
    DateTime start = DateTime.Now;
    try
    {
        new SqlConnection(csb.ToString()).Open();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    finally
    {
        Console.Write(string.Format("{0} seconds", DateTime.Now.Subtract(start).TotalSeconds));
    }
}

我得到这个结果:

A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
47.6097605 seconds

我希望ConnectTimeout属性有效.那么为什么在这种情况下会忽略ConnectTimeout属性呢?(我也很好奇其他人看到的时间).

更新:我注意到以下额外的行将时间跨度缩短到26秒???

csb.FailoverPartner=@"9.9.9.9";

kd7.. 7

编辑:这看起来很奇怪,我在反编译代码中加入了一个断点,并使用 - > VALID < - 服务器名称将超时设置为1 ,我让断点坐在那里然后继续,它给了预期的超时过期异常所以看起来ConnectTimeout仅在能够解析服务器并等待连接时才适用.不会影响解析要连接的服务器.我认为正在经历的时间是服务器解析而不是实际的"连接"行为.至少这是我目前的假设.

我用反射器看看封面下发生了什么.也许微软的某个人可以帮助我们,因为我还发现ConnectTimeout似乎对初始连接没有影响.

无论如何在内部建立连接,调用以下方法,按此顺序我想:

  internal DbConnectionInternal CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
    {
      DbConnectionPoolGroupProviderInfo providerInfo = pool.PoolGroup.ProviderInfo;
      DbConnectionInternal internal2 = this.CreateConnection(options, providerInfo, pool, owningConnection);
      if (internal2 != null)
      {
        this.PerformanceCounters.HardConnectsPerSecond.Increment();
        internal2.MakePooledConnection(pool);
      }
      Bid.Trace(" %d#, Pooled database connection created.\n", this.ObjectID);
      return internal2;
    }

然后:

 protected override DbConnectionInternal CreateConnection(DbConnectionOptions options, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)
    {
      string instanceName;
      SqlConnectionString str = (SqlConnectionString) options;
      if (str.ContextConnection)
      {
        return this.GetContextConnection(str, poolGroupProviderInfo, owningConnection);
      }
      bool redirectedUserInstance = false;
      DbConnectionPoolIdentity current = null;
      if (str.IntegratedSecurity)
      {
        if (pool != null)
        {
          current = pool.Identity;
        }
        else
        {
          current = DbConnectionPoolIdentity.GetCurrent();
        }
      }
      if (!str.UserInstance)
      {
        goto Label_00F1;
      }
      redirectedUserInstance = true;
      if ((pool == null) || ((pool != null) && (pool.Count <= 0)))
      {
        using (SqlInternalConnectionTds tds = null)
        {
          SqlConnectionString connectionOptions = new SqlConnectionString(str, str.DataSource, true, false);
          tds = new SqlInternalConnectionTds(current, connectionOptions, null, "", null, false);
          instanceName = tds.InstanceName;
          if (!instanceName.StartsWith(@"\\.\", StringComparison.Ordinal))
          {
            throw SQL.NonLocalSSEInstance();
          }
          if (pool != null)
          {
            SqlConnectionPoolProviderInfo info2 = (SqlConnectionPoolProviderInfo) pool.ProviderInfo;
            info2.InstanceName = instanceName;
          }
          goto Label_00DB;
        }
      }
      SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo) pool.ProviderInfo;
      instanceName = providerInfo.InstanceName;
    Label_00DB:
      str = new SqlConnectionString(str, instanceName, false, null);
      poolGroupProviderInfo = null;
    Label_00F1:
      return new SqlInternalConnectionTds(current, str, poolGroupProviderInfo, "", (SqlConnection) owningConnection, redirectedUserInstance);
    }

然后:

 internal SqlInternalConnectionTds(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, object providerInfo, string newPassword, SqlConnection owningObject, bool redirectedUserInstance) : base(connectionOptions)
    {
      this._instanceName = string.Empty;
      if (connectionOptions.UserInstance && InOutOfProcHelper.InProc)
      {
        throw SQL.UserInstanceNotAvailableInProc();
      }
      this._identity = identity;
      this._poolGroupProviderInfo = (SqlConnectionPoolGroupProviderInfo) providerInfo;
      this._fResetConnection = connectionOptions.ConnectionReset;
      if (this._fResetConnection)
      {
        this._originalDatabase = connectionOptions.InitialCatalog;
        this._originalLanguage = connectionOptions.CurrentLanguage;
      }
      RuntimeHelpers.PrepareConstrainedRegions();
      try
      {
        TimeoutTimer timeout = TimeoutTimer.StartSecondsTimeout(connectionOptions.ConnectTimeout);
        this.OpenLoginEnlist(owningObject, timeout, connectionOptions, newPassword, redirectedUserInstance);
      }
      catch (OutOfMemoryException)
      {
        base.DoomThisConnection();
        throw;
      }
      catch (StackOverflowException)
      {
        base.DoomThisConnection();
        throw;
      }
      catch (ThreadAbortException)
      {
        base.DoomThisConnection();
        throw;
      }
      if (Bid.AdvancedOn)
      {
        Bid.Trace(" %d#, constructed new TDS internal connection\n", base.ObjectID);
      }
    }

然后,默认情况下(没有故障转移伙伴):

private void LoginNoFailover(ServerInfo serverInfo, string newPassword, bool redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout)
    {
      if (Bid.AdvancedOn)
      {
        Bid.Trace(" %d#, host=%ls\n", base.ObjectID, serverInfo.UserServerName);
      }
      int num = 100;
      this.ResolveExtendedServerName(serverInfo, !redirectedUserInstance, owningObject);
      while (true)
      {
        if (this._parser != null)
        {
          this._parser.Disconnect();
        }
        this._parser = new TdsParser(base.ConnectionOptions.MARS, base.ConnectionOptions.Asynchronous);
        try
        {
          this.AttemptOneLogin(serverInfo, newPassword, true, timeout, owningObject);
          break;
        }
        catch (SqlException exception)
        {
          if (((this._parser == null) || (this._parser.State != TdsParserState.Closed)) || (this.IsDoNotRetryConnectError(exception.Number) || timeout.IsExpired))
          {
            throw;
          }
          if (timeout.MillisecondsRemaining <= num)
          {
            throw;
          }
        }
        if (this.ServerProvidedFailOverPartner != null)
        {
          this.LoginWithFailover(true, serverInfo, this.ServerProvidedFailOverPartner, newPassword, redirectedUserInstance, owningObject, connectionOptions, timeout);
          return;
        }
        if (Bid.AdvancedOn)
        {
          Bid.Trace(" %d#, sleeping %d{milisec}\n", base.ObjectID, num);
        }
        Thread.Sleep(num);
        num = (num < 500) ? (num * 2) : 0x3e8;
      }
      if (this.PoolGroupProviderInfo != null)
      {
        this.PoolGroupProviderInfo.FailoverCheck(this, false, connectionOptions, this.ServerProvidedFailOverPartner);
      }
      base.CurrentDataSource = serverInfo.UserServerName;
    } 

然后:

internal void Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, bool ignoreSniOpenTimeout, long timerExpire, bool encrypt, bool trustServerCert, bool integratedSecurity)
    {
      if (this._state == TdsParserState.Closed)
      {
        this._connHandler = connHandler;
        if (SNILoadHandle.SingletonInstance.SNIStatus != 0)
        {
          this.Errors.Add(this.ProcessSNIError(this._physicalStateObj));
          this._physicalStateObj.Dispose();
          this.ThrowExceptionAndWarning();
        }
        if (integratedSecurity)
        {
          this.LoadSSPILibrary();
          this._sniServerUserName = new byte[s_maxSSPILength];
          Bid.Trace(" SSPI authentication\n");
        }
        else
        {
          Bid.Trace(" SQL authentication\n");
        }
        byte[] instanceName = null;
        this._physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, integratedSecurity, this._sniServerUserName, false, this._fAsync);
        if (this._physicalStateObj.Status != 0)
        {
          this.Errors.Add(this.ProcessSNIError(this._physicalStateObj));
          this._physicalStateObj.Dispose();
          Bid.Trace(" Login failure\n");
          this.ThrowExceptionAndWarning();
        }
        this._server = serverInfo.ResolvedServerName;
        if (connHandler.PoolGroupProviderInfo != null)
        {
          connHandler.PoolGroupProviderInfo.AliasCheck(serverInfo.ResolvedServerName);
        }
        this._state = TdsParserState.OpenNotLoggedIn;
        this._physicalStateObj.SniContext = SniContext.Snix_PreLoginBeforeSuccessfullWrite;
        this._physicalStateObj.TimeoutTime = timerExpire;
        bool marsCapable = false;
        this.SendPreLoginHandshake(instanceName, encrypt);
        this._physicalStateObj.SniContext = SniContext.Snix_PreLogin;
        switch (this.ConsumePreLoginHandshake(encrypt, trustServerCert, out marsCapable))
        {
          case PreLoginHandshakeStatus.SphinxFailure:
            this._fMARS = false;
            this._physicalStateObj._sniPacket = null;
            this._physicalStateObj.SniContext = SniContext.Snix_Connect;
            this._physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, integratedSecurity, this._sniServerUserName, false, this._fAsync);
            if (this._physicalStateObj.Status != 0)
            {
              this.Errors.Add(this.ProcessSNIError(this._physicalStateObj));
              Bid.Trace(" Login failure\n");
              this.ThrowExceptionAndWarning();
            }
            break;

          case PreLoginHandshakeStatus.InstanceFailure:
            this._physicalStateObj.Dispose();
            this._physicalStateObj.SniContext = SniContext.Snix_Connect;
            this._physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, integratedSecurity, this._sniServerUserName, true, this._fAsync);
            if (this._physicalStateObj.Status != 0)
            {
              this.Errors.Add(this.ProcessSNIError(this._physicalStateObj));
              Bid.Trace(" Login failure\n");
              this.ThrowExceptionAndWarning();
            }
            this.SendPreLoginHandshake(instanceName, encrypt);
            if (this.ConsumePreLoginHandshake(encrypt, trustServerCert, out marsCapable) == PreLoginHandshakeStatus.InstanceFailure)
            {
              Bid.Trace(" Login failure\n");
              throw SQL.InstanceFailure();
            }
            break;
        }
        if (this._fMARS && marsCapable)
        {
          this._sessionPool = new TdsParserSessionPool(this);
        }
        else
        {
          this._fMARS = false;
        }
      }
    }

我不确定这一切是如何组合在一起的,但无限的时间似乎是真的.

不确定这是否有帮助,但我认为值得深入研究

在此输入图像描述

在此输入图像描述



1> kd7..:

编辑:这看起来很奇怪,我在反编译代码中加入了一个断点,并使用 - > VALID < - 服务器名称将超时设置为1 ,我让断点坐在那里然后继续,它给了预期的超时过期异常所以看起来ConnectTimeout仅在能够解析服务器并等待连接时才适用.不会影响解析要连接的服务器.我认为正在经历的时间是服务器解析而不是实际的"连接"行为.至少这是我目前的假设.

我用反射器看看封面下发生了什么.也许微软的某个人可以帮助我们,因为我还发现ConnectTimeout似乎对初始连接没有影响.

无论如何在内部建立连接,调用以下方法,按此顺序我想:

  internal DbConnectionInternal CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
    {
      DbConnectionPoolGroupProviderInfo providerInfo = pool.PoolGroup.ProviderInfo;
      DbConnectionInternal internal2 = this.CreateConnection(options, providerInfo, pool, owningConnection);
      if (internal2 != null)
      {
        this.PerformanceCounters.HardConnectsPerSecond.Increment();
        internal2.MakePooledConnection(pool);
      }
      Bid.Trace(" %d#, Pooled database connection created.\n", this.ObjectID);
      return internal2;
    }

然后:

 protected override DbConnectionInternal CreateConnection(DbConnectionOptions options, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)
    {
      string instanceName;
      SqlConnectionString str = (SqlConnectionString) options;
      if (str.ContextConnection)
      {
        return this.GetContextConnection(str, poolGroupProviderInfo, owningConnection);
      }
      bool redirectedUserInstance = false;
      DbConnectionPoolIdentity current = null;
      if (str.IntegratedSecurity)
      {
        if (pool != null)
        {
          current = pool.Identity;
        }
        else
        {
          current = DbConnectionPoolIdentity.GetCurrent();
        }
      }
      if (!str.UserInstance)
      {
        goto Label_00F1;
      }
      redirectedUserInstance = true;
      if ((pool == null) || ((pool != null) && (pool.Count <= 0)))
      {
        using (SqlInternalConnectionTds tds = null)
        {
          SqlConnectionString connectionOptions = new SqlConnectionString(str, str.DataSource, true, false);
          tds = new SqlInternalConnectionTds(current, connectionOptions, null, "", null, false);
          instanceName = tds.InstanceName;
          if (!instanceName.StartsWith(@"\\.\", StringComparison.Ordinal))
          {
            throw SQL.NonLocalSSEInstance();
          }
          if (pool != null)
          {
            SqlConnectionPoolProviderInfo info2 = (SqlConnectionPoolProviderInfo) pool.ProviderInfo;
            info2.InstanceName = instanceName;
          }
          goto Label_00DB;
        }
      }
      SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo) pool.ProviderInfo;
      instanceName = providerInfo.InstanceName;
    Label_00DB:
      str = new SqlConnectionString(str, instanceName, false, null);
      poolGroupProviderInfo = null;
    Label_00F1:
      return new SqlInternalConnectionTds(current, str, poolGroupProviderInfo, "", (SqlConnection) owningConnection, redirectedUserInstance);
    }

然后:

 internal SqlInternalConnectionTds(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, object providerInfo, string newPassword, SqlConnection owningObject, bool redirectedUserInstance) : base(connectionOptions)
    {
      this._instanceName = string.Empty;
      if (connectionOptions.UserInstance && InOutOfProcHelper.InProc)
      {
        throw SQL.UserInstanceNotAvailableInProc();
      }
      this._identity = identity;
      this._poolGroupProviderInfo = (SqlConnectionPoolGroupProviderInfo) providerInfo;
      this._fResetConnection = connectionOptions.ConnectionReset;
      if (this._fResetConnection)
      {
        this._originalDatabase = connectionOptions.InitialCatalog;
        this._originalLanguage = connectionOptions.CurrentLanguage;
      }
      RuntimeHelpers.PrepareConstrainedRegions();
      try
      {
        TimeoutTimer timeout = TimeoutTimer.StartSecondsTimeout(connectionOptions.ConnectTimeout);
        this.OpenLoginEnlist(owningObject, timeout, connectionOptions, newPassword, redirectedUserInstance);
      }
      catch (OutOfMemoryException)
      {
        base.DoomThisConnection();
        throw;
      }
      catch (StackOverflowException)
      {
        base.DoomThisConnection();
        throw;
      }
      catch (ThreadAbortException)
      {
        base.DoomThisConnection();
        throw;
      }
      if (Bid.AdvancedOn)
      {
        Bid.Trace(" %d#, constructed new TDS internal connection\n", base.ObjectID);
      }
    }

然后,默认情况下(没有故障转移伙伴):

private void LoginNoFailover(ServerInfo serverInfo, string newPassword, bool redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout)
    {
      if (Bid.AdvancedOn)
      {
        Bid.Trace(" %d#, host=%ls\n", base.ObjectID, serverInfo.UserServerName);
      }
      int num = 100;
      this.ResolveExtendedServerName(serverInfo, !redirectedUserInstance, owningObject);
      while (true)
      {
        if (this._parser != null)
        {
          this._parser.Disconnect();
        }
        this._parser = new TdsParser(base.ConnectionOptions.MARS, base.ConnectionOptions.Asynchronous);
        try
        {
          this.AttemptOneLogin(serverInfo, newPassword, true, timeout, owningObject);
          break;
        }
        catch (SqlException exception)
        {
          if (((this._parser == null) || (this._parser.State != TdsParserState.Closed)) || (this.IsDoNotRetryConnectError(exception.Number) || timeout.IsExpired))
          {
            throw;
          }
          if (timeout.MillisecondsRemaining <= num)
          {
            throw;
          }
        }
        if (this.ServerProvidedFailOverPartner != null)
        {
          this.LoginWithFailover(true, serverInfo, this.ServerProvidedFailOverPartner, newPassword, redirectedUserInstance, owningObject, connectionOptions, timeout);
          return;
        }
        if (Bid.AdvancedOn)
        {
          Bid.Trace(" %d#, sleeping %d{milisec}\n", base.ObjectID, num);
        }
        Thread.Sleep(num);
        num = (num < 500) ? (num * 2) : 0x3e8;
      }
      if (this.PoolGroupProviderInfo != null)
      {
        this.PoolGroupProviderInfo.FailoverCheck(this, false, connectionOptions, this.ServerProvidedFailOverPartner);
      }
      base.CurrentDataSource = serverInfo.UserServerName;
    } 

然后:

internal void Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, bool ignoreSniOpenTimeout, long timerExpire, bool encrypt, bool trustServerCert, bool integratedSecurity)
    {
      if (this._state == TdsParserState.Closed)
      {
        this._connHandler = connHandler;
        if (SNILoadHandle.SingletonInstance.SNIStatus != 0)
        {
          this.Errors.Add(this.ProcessSNIError(this._physicalStateObj));
          this._physicalStateObj.Dispose();
          this.ThrowExceptionAndWarning();
        }
        if (integratedSecurity)
        {
          this.LoadSSPILibrary();
          this._sniServerUserName = new byte[s_maxSSPILength];
          Bid.Trace(" SSPI authentication\n");
        }
        else
        {
          Bid.Trace(" SQL authentication\n");
        }
        byte[] instanceName = null;
        this._physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, integratedSecurity, this._sniServerUserName, false, this._fAsync);
        if (this._physicalStateObj.Status != 0)
        {
          this.Errors.Add(this.ProcessSNIError(this._physicalStateObj));
          this._physicalStateObj.Dispose();
          Bid.Trace(" Login failure\n");
          this.ThrowExceptionAndWarning();
        }
        this._server = serverInfo.ResolvedServerName;
        if (connHandler.PoolGroupProviderInfo != null)
        {
          connHandler.PoolGroupProviderInfo.AliasCheck(serverInfo.ResolvedServerName);
        }
        this._state = TdsParserState.OpenNotLoggedIn;
        this._physicalStateObj.SniContext = SniContext.Snix_PreLoginBeforeSuccessfullWrite;
        this._physicalStateObj.TimeoutTime = timerExpire;
        bool marsCapable = false;
        this.SendPreLoginHandshake(instanceName, encrypt);
        this._physicalStateObj.SniContext = SniContext.Snix_PreLogin;
        switch (this.ConsumePreLoginHandshake(encrypt, trustServerCert, out marsCapable))
        {
          case PreLoginHandshakeStatus.SphinxFailure:
            this._fMARS = false;
            this._physicalStateObj._sniPacket = null;
            this._physicalStateObj.SniContext = SniContext.Snix_Connect;
            this._physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, integratedSecurity, this._sniServerUserName, false, this._fAsync);
            if (this._physicalStateObj.Status != 0)
            {
              this.Errors.Add(this.ProcessSNIError(this._physicalStateObj));
              Bid.Trace(" Login failure\n");
              this.ThrowExceptionAndWarning();
            }
            break;

          case PreLoginHandshakeStatus.InstanceFailure:
            this._physicalStateObj.Dispose();
            this._physicalStateObj.SniContext = SniContext.Snix_Connect;
            this._physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, integratedSecurity, this._sniServerUserName, true, this._fAsync);
            if (this._physicalStateObj.Status != 0)
            {
              this.Errors.Add(this.ProcessSNIError(this._physicalStateObj));
              Bid.Trace(" Login failure\n");
              this.ThrowExceptionAndWarning();
            }
            this.SendPreLoginHandshake(instanceName, encrypt);
            if (this.ConsumePreLoginHandshake(encrypt, trustServerCert, out marsCapable) == PreLoginHandshakeStatus.InstanceFailure)
            {
              Bid.Trace(" Login failure\n");
              throw SQL.InstanceFailure();
            }
            break;
        }
        if (this._fMARS && marsCapable)
        {
          this._sessionPool = new TdsParserSessionPool(this);
        }
        else
        {
          this._fMARS = false;
        }
      }
    }

我不确定这一切是如何组合在一起的,但无限的时间似乎是真的.

不确定这是否有帮助,但我认为值得深入研究

在此输入图像描述

在此输入图像描述

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有