Best way to do nothing until things are connected in C#
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
{
}
}
精彩评论