C# 在C语言中连接东西之前什么都不做的最佳方法#

C# 在C语言中连接东西之前什么都不做的最佳方法#,c#,database-connection,wait,C#,Database Connection,Wait,我正在审查我正在开发的一个应用程序中连接到DB的代码,我看到了这一点 if (_dbConnection == null) _dbConnection = GetConnection(); while (_dbConnection.State == ConnectionState.Connecting) { //Do Nothing until things are connected. } if (_dbConnection.State != Connecti

我正在审查我正在开发的一个应用程序中连接到DB的代码,我看到了这一点

 if (_dbConnection == null)
     _dbConnection = GetConnection();

 while (_dbConnection.State == ConnectionState.Connecting)
 {
     //Do Nothing until things are connected.
 }

 if (_dbConnection.State != ConnectionState.Open)
     _dbConnection.Open();

 var command = GetCommand(commandType);
 command.Connection = _dbConnection;
 return command;
while循环让我担心。有没有更好的方法在事情联系起来之前什么都不做

编辑:

连接如下所示

private static IDbConnection GetConnection()
{
     return new SqlConnection(ConfigurationManager.ConnectionStrings["CoonectionStringName"].ConnectionString);
}

考虑到这是一个web应用程序,最好的方法是计算自您开始尝试连接和转义(如果超过超时时间)以来经过的时间。显然,此时抛出异常或处理情况

var startTime = DateTime.Now;
var endTime = DateTime.Now.AddSeconds(5);
var timeOut = false;

while (_dbConnection.State == ConnectionState.Connecting)
{
    if (DateTime.Now.Compare(endTime) >= 0
    {
        timeOut = true;
        break;
    }
}

if (timeOut)
{
    // TODO: Handle your time out here.
}

编辑:请注意,这适用于
DbConnection
而不是
IDbConnection

您始终可以使用DbConnection类的StateChange事件,而不是while循环


检查

尽管循环确实起作用,并且是等待某些后台操作的有效策略,但其他答案似乎遗漏了一个关键点;你必须让后台操作做一些工作。翻转一段时间的循环不是很有效率,但是Windows会考虑应用程序的主线程,这可能是等待的重要性,并且在后台操作获得CPU时钟的单个时钟之前,将循环数百次或数千次。 为了避免这种情况,请使用Thread.Yield()语句告诉处理器在等待CPU时间的所有其他线程中旋转,并在完成后返回。这允许计算机在您等待后台进程时完成一些工作,而不是垄断CPU在基本上为空的循环中运行。这真的很简单;以下是贾斯汀的答案:

var startTime = DateTime.Now;
var endTime = DateTime.Now.AddSeconds(5);
var timeOut = false;

while (_dbConnection.State == ConnectionState.Connecting)
{
    if (DateTime.Now.CompareTo(endTime) >= 0)
    {
        timeOut = true;
        break;
    }
    Thread.Yield(); //tells the kernel to give other threads some time
}

if (timeOut)
{
    Console.WriteLine("Connection Timeout");
    // TODO: Handle your time out here.
}

钩住StateChange事件上的处理程序。 当国家开放时,做需要做的事

            m_SqlConnection = new SqlConnection(ConnectionStringBuilder.ConnectionString);
            m_SqlConnection.StateChange += new System.Data.StateChangeEventHandler(m_SqlConnection_StateChange);
            m_SqlConnection.Open();



    void m_SqlConnection_StateChange(object sender, System.Data.StateChangeEventArgs e)
    {
        try
        {
            if (m_SqlConnection.State == ConnectionState.Open)
            {
                //do stuff
            }
            if (m_SqlConnection.State == ConnectionState.Broken)
            {
                Close();
            }
            if (m_SqlConnection.State == ConnectionState.Closed)
            {
                Open();
            }
        }
        catch
        {

        }
    }

什么样的联系?System.Data.SqlClient.SqlConnection?我会设置一个超时,并在while循环中放入一个delay/wait语句,这样您就不会浪费CPU时间连接的类是System.Data.IDbConnection您可以使用DbConnection而不是IDbConnection吗?我真的不知道这两者之间的区别。我想我可以。只是想知道。如果连接从未出现怎么办?事件永远不会触发吗?@tou:这应该由连接超时异常处理单独解决……这完全有效吗?如果返回相同的连接怎么办?您需要累积处理程序。@Kit:您能否详细说明“如果返回了相同的连接怎么办?”在不知道
GetConnection()
的实现(例如,它可能是一个缓存连接的静态方法)的情况下,对上述代码的多次调用可能会执行
\u connection.StateChange+=(s,e)=>{
),这可能会导致每次连续调用被调用代码时调用更多的处理程序。在这种情况下,while循环仍在运行,并占用大量处理器时间。我不建议这样做,因为每次状态更改都在不同的线程上运行,使用不同线程的连接时可能会导致不一致,