开发者

Best way to do nothing until things are connected in C#

开发者 https://www.devze.com 2023-03-12 21:50 出处:网络
I was reviewing the code to connect to the DB i开发者_开发百科n one of the applications that I\'m working on and I saw this

I was reviewing the code to connect to the DB i开发者_开发百科n one of the applications that I'm working on and I saw this

 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;

The while loop worries me. Is there a better way to Do Nothing until things are connected?

EDIT:

The connection is gotten as follows

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


Though the loop does work and is a valid strategy for waiting on some background operation, other answers seem to miss a key point; you have to let the background operation do some work. Churning through a while loop isn't very productive, but Windows will consider the app's main thread, which is probably what's doing the waiting, to be of high importance, and will spin through the loop hundreds or thousands of times before the background operation ever gets a single clock of CPU time.

To avoid this, use the Thread.Yield() statement to tell the processor to spin through all the other threads awaiting CPU time and come back when they're done. This allows the computer to get some work done while you're waiting on the background process, instead of monopolizing the CPU to spin through a basically empty loop. It's real simple; here's Justin's answer revised:

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


EDIT: Please note that this works for DbConnection and not IDbConnection

You can always use the StateChange event of the DbConnection class instead of the while loop.

Check this


Considering this is a web application, the best thing to do is to calculate the duration of time elapsed since you started trying to connect and escape if it exceeds a timeout period. Obviously, throw an exception or handle the situation at that point.

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


Hook an handler on the StateChange event. When the State is Open, do what's needed.

            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
        {

        }
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号