Robert
Robert

Reputation: 1726

Loop until condition is met or time has elapsed

In my application, I have an object with the field DependentPC, which can hold either an IP Address OR a network share. If it's an IP Address, it does a simple Ping and stores the results, but if it's a network share, I need it to keep checking the share until it exists OR a specified time has elapsed. Here's what I've got so far:

//Determines if it's a network share or not.
if (appToRun.DependentPC.Contains(@"\"))
{
    var startTime = DateTime.Now;
    var directoryInfo = new DirectoryInfo(appToRun.DependentPC);

    //do until true or timeout reached.
    while (DateTime.Now - startTime < TimeSpan.FromSeconds(Convert.ToInt32(DependentPCTimeout)) || !directoryInfo.Exists) { }

    if (!directoryInfo.Exists)
    {
        XtraMessageBox.Show($"Could not find or get a reply from the computer share '{appToRun.DependentPC}'. ", $"{appToRun.DependentPC} Not Found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        return false;
    }
}
else
{
    //Ping computer.
    if (PingComputer(appToRun.DependentPC) != IPStatus.Success)
    {
        XtraMessageBox.Show($"Could not find or get a reply from the computer '{appToRun.DependentPC}'. ", $"{appToRun.DependentPC} Not Found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        return false;
    }
}

The value for the variable DependentPCTimeout is 50 and the network share is "\192.168.103.100\WorkingFolder. So this works, to a point. When using a network share, it appears to always wait until the time has elapsed before continuing, even if the directory exists. I tried to use a single OR | with the while loop but that seems to make it lock up forever.

Upvotes: 0

Views: 1514

Answers (2)

Vivien Sonntag
Vivien Sonntag

Reputation: 4639

You need to check while both conditions are true, not while one of them is true. So you need to use an AND and not an OR:

//Determines if it's a network share or not.
if (appToRun.DependentPC.Contains(@"\"))
{
    var startTime = DateTime.Now;
    var directoryInfo = new DirectoryInfo(appToRun.DependentPC);

    //wait until directory exists or timeout reached.
    while (DateTime.Now - startTime < TimeSpan.FromSeconds(Convert.ToInt32(DependentPCTimeout)) && !directoryInfo.Exists) { }

    if (!directoryInfo.Exists)
    {
        XtraMessageBox.Show($"Could not find or get a reply from the computer share '{appToRun.DependentPC}'. ", $"{appToRun.DependentPC} Not Found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        return false;
    }
}
else
{
    //Ping computer.
    if (PingComputer(appToRun.DependentPC) != IPStatus.Success)
    {
        XtraMessageBox.Show($"Could not find or get a reply from the computer '{appToRun.DependentPC}'. ", $"{appToRun.DependentPC} Not Found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        return false;
    }
}

Upvotes: 0

Edward N
Edward N

Reputation: 997

When an OR operator is used in a condition statement, if the first condition is TRUE, the rest will be skipped.

In your case, the DateTime.Now - startTime < TimeSpan.FromSeconds(...) always true in a period of time.

I would suggest that you can implement like this ways

//do until true or timeout reached.
  while (!directoryInfo.Exists) { 
    if (DateTime.Now - startTime > TimeSpan.FromSeconds(Convert.ToInt32(DependentPCTimeout)))
        break;
  }

Upvotes: 3

Related Questions