Het lijkt erop dat alle gevallen die lange vertragingen veroorzaakten, veel konden worden opgelost sneller door een directe socketverbinding als volgt te proberen:
foreach (string svrName in args)
{
try
{
System.Net.Sockets.TcpClient tcp = new System.Net.Sockets.TcpClient(svrName, 1433);
if (tcp.Connected)
Console.WriteLine("Opened connection to {0}", svrName);
else
Console.WriteLine("{0} not connected", svrName);
tcp.Close();
}
catch (Exception ex)
{
Console.WriteLine("Error connecting to {0}: {1}", svrName, ex.Message);
}
}
Ik ga deze code gebruiken om te controleren of de server reageert op de SQL Server-poort en alleen proberen een verbinding te openen als dit het geval is. Ik dacht (op basis van de ervaring van anderen) dat er zelfs op dit niveau een vertraging van 30 seconden zou zijn, maar ik krijg meteen de melding dat de machine "actief de verbinding heeft geweigerd".
Bewerken: En als de machine niet bestaat, zegt hij dat ook meteen. Geen vertragingen van 30 seconden die ik kan vinden.
Bewerken: Machines die op het netwerk waren maar niet zijn uitgeschakeld, hebben nog steeds 30 seconden nodig om te falen, denk ik. De machines met firewalls falen echter sneller.
Bewerken: Hier is de bijgewerkte code. Ik heb het gevoel dat het schoner is om een socket te sluiten dan een thread af te breken:
static void TestConn(string server)
{
try
{
using (System.Net.Sockets.TcpClient tcpSocket = new System.Net.Sockets.TcpClient())
{
IAsyncResult async = tcpSocket.BeginConnect(server, 1433, ConnectCallback, null);
DateTime startTime = DateTime.Now;
do
{
System.Threading.Thread.Sleep(500);
if (async.IsCompleted) break;
} while (DateTime.Now.Subtract(startTime).TotalSeconds < 5);
if (async.IsCompleted)
{
tcpSocket.EndConnect(async);
Console.WriteLine("Connection succeeded");
}
tcpSocket.Close();
if (!async.IsCompleted)
{
Console.WriteLine("Server did not respond");
return;
}
}
}
catch(System.Net.Sockets.SocketException ex)
{
Console.WriteLine(ex.Message);
}
}