2011-12-08 16 views
11

código base de mi empresa contiene la siguiente línea C#:Uso Directory.Exists en una carpeta de red cuando la red está abajo

bool pathExists = Directory.Exists(path); 

En tiempo de ejecución, la cadena path pasa a ser la dirección de una carpeta en la empresa de Intranet: algo así como \\company\companyFolder. Cuando la conexión de mi máquina con Windows a la intranet está activa, funciona bien. Sin embargo, cuando la conexión se desactiva (como lo hizo hoy), la ejecución de la línea anterior hace que la aplicación se congele por completo. Solo puedo cerrar la aplicación matándola con el Administrador de tareas.

Por supuesto, preferiría tener Directory.Exists(path) devolver false en este escenario. ¿Hay alguna forma de hacer esto?

Respuesta

11

No hay forma de cambiar el comportamiento de Directory.Exists para este escenario. Debajo del capó está haciendo una solicitud sincrónica a través de la red en el hilo de UI. Si la conexión de red se cuelga debido a una interrupción, demasiado tráfico, etc., hará que el subproceso de la interfaz de usuario se cuelgue también.

Lo mejor que puede hacer es realizar esta solicitud desde un hilo de fondo y darse por vencido explícitamente después de un cierto tiempo. Por ejemplo

Func<bool> func =() => Directory.Exists(path); 
Task<bool> task = new Task<bool>(func); 
task.Start(); 
if (task.Wait(100)) { 
    return task.Value; 
} else { 
    // Didn't get an answer back in time be pessimistic and assume it didn't exist 
    return false; 
} 
+3

Esto podría engullir fácilmente todos los subprocesos disponibles en el grupo de subprocesos y causar más problemas dentro de la aplicación. Si va a hacer algo como esto, debe poder terminar la operación después de que haya transcurrido el tiempo de espera. –

+0

@ csharptest.net ese es el problema, no puedes. El método 'Directory.Exists' no puede controlarse por los tiempos de espera y, dado que, en esencia, desciende inmediatamente al evento de código nativo, un' Thread.Abort' no lo ayudará. – JaredPar

1

Si la conectividad de red general es su principal problema, podría intentar probar la conectividad de red antes de esto:

[DllImport("WININET", CharSet = CharSet.Auto)] 
    static extern bool InternetGetConnectedState(ref int lpdwFlags, int dwReserved); 

    public static bool Connected 
    { 
     get 
     { 
      int flags = 0; 
      return InternetGetConnectedState(ref flags, 0); 
     } 
    } 

luego determinar si la ruta es una ruta UNC y devolver false si el la red está fuera de línea:

public static bool FolderExists(string directory) 
    { 
     if (new Uri(directory, UriKind.Absolute).IsUnc && !Connected) 
      return false; 
     return System.IO.Directory.Exists(directory); 
    } 

Nada de esto ayuda cuando el host al que intentas conectarte está desconectado. En ese caso, aún tiene tiempo de espera de red de 2 minutos.

Cuestiones relacionadas