2012-08-08 11 views
6

tenemos un archivador NAS de NetApp que de vez en cuando parece fallar, no estoy seguro de si esto depende de problemas de red, cargas pesadas o el propio Filer; el problema es que el comando usual System.IO.File.Copy(...) falla algunas veces inesperadamente mientras funcionó un minuto antes y vuelve a funcionar un minuto después ... Filer está trabajando con el sistema de archivos CIFS.Copiar archivos de forma segura en NAS Filer

en mis archivos de registro Log4net veo la excepción:

System.IO.IOException: El nombre de red especificado ya no está disponible . en System.IO .__ Error.WinIOError (Int32 errorCode, Cadena maybeFullPath) ...

equipo de red está seguro de lo que sucede y por qué, ahora he pensando si puedo implementar un sistema simple intento/reintento para copiar el archivo y vuelva a intentar la copia en caso de falla, es posible que System.IO.File.Copy no se haya diseñado para el almacenamiento CIFS, sino para unidades NTFS normales o almacenamiento de red estable.

¿Hay patrones comunes o clases .NET adecuadas para hacer esto copiar y reintentar o debería simplemente usar un enfoque como en el siguiente pseudo-código?

while(!copied && count <5) 
{ 
    count++; 

    try 
    { 
    //here copy the file 
    ... 

    //if no exception copy was ok 
    copied = true; 
    } 
    catch 
    { 
    if(count >= 5) 
    { 
     // Log that retry limit has been reached... 
    } 
    else 
    { 
     // make thread to wait for some time, 
     // waiting time can be in function of count or fixed... 
    } 
    } 
} 
+2

'System.IO.File.Copy()' se reduce a la función Win32 ['CopyFile'] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363851.aspx) . Entonces codifico algo que usa eso repetidamente y veo si falla también. Creo que estás tratando de poner una banda de software en un problema mayor. –

+1

Configura un 'ping -t nombre de host' y lo registra en un archivo. Déjalo funcionar durante unas horas y luego busque los tiempos de espera. Eso debería decirle si el problema está relacionado con la red. Todavía podría ser un problema con el dispositivo en sí, pero al menos se puede descartar un problema de .NET. –

+0

Me gusta ese bucle. Posible poner una pequeña espera en la captura. – Paparazzi

Respuesta

1

después de semanas y semanas de investigación, pruebas y dolor por fin parece haber encontrado una solución de trabajo, decidió sustituir el método System.IO.File.Copy con invocación de Microsoft Robocopy command que está disponible en Windows Server 2008 R2 y parecía funcionar bien desde el primer tratar. Esto me hace sentir cómodo de que no estoy reinventando la rueda sino usando una tecnología probada diseñada exactamente para mis necesidades. gracias a todos por sus respuestas y comentarios de todos modos.

2

Lo mismo me pasa. Tengo un viejo NAS Server y de vez en cuando Windows shows an error telling me that the drive is not accessible anymore.
para gestionar el file copy process tal vez usted podría usar en su lugar CopyFileEx (de Windows API) como se muestra en la siguiente muestra:

public class SecureFileCopy 
{ 
    public static void CopyFile(FileInfo source, FileInfo destination, 
     CopyFileOptions options, CopyFileCallback callback, object state) 
    { 
     if (source == null) throw new ArgumentNullException("source"); 
     if (destination == null) 
      throw new ArgumentNullException("destination"); 
     if ((options & ~CopyFileOptions.All) != 0) 
      throw new ArgumentOutOfRangeException("options"); 

     new FileIOPermission(
      FileIOPermissionAccess.Read, source.FullName).Demand(); 
     new FileIOPermission(
      FileIOPermissionAccess.Write, destination.FullName).Demand(); 

     CopyProgressRoutine cpr = callback == null ? 
      null : new CopyProgressRoutine(new CopyProgressData(
       source, destination, callback, state).CallbackHandler); 

     bool cancel = false; 
     if (!CopyFileEx(source.FullName, destination.FullName, cpr, 
      IntPtr.Zero, ref cancel, (int)options)) 
     { 
      throw new IOException(new Win32Exception().Message); 
     } 
    } 

    private class CopyProgressData 
    { 
     private FileInfo _source = null; 
     private FileInfo _destination = null; 
     private CopyFileCallback _callback = null; 
     private object _state = null; 

     public CopyProgressData(FileInfo source, FileInfo destination, 
      CopyFileCallback callback, object state) 
     { 
      _source = source; 
      _destination = destination; 
      _callback = callback; 
      _state = state; 
     } 

     public int CallbackHandler(
      long totalFileSize, long totalBytesTransferred, 
      long streamSize, long streamBytesTransferred, 
      int streamNumber, int callbackReason, 
      IntPtr sourceFile, IntPtr destinationFile, IntPtr data) 
     { 
      return (int)_callback(_source, _destination, _state, 
       totalFileSize, totalBytesTransferred); 
     } 
    } 

    private delegate int CopyProgressRoutine(
     long totalFileSize, long TotalBytesTransferred, long streamSize, 
     long streamBytesTransferred, int streamNumber, int callbackReason, 
     IntPtr sourceFile, IntPtr destinationFile, IntPtr data); 

    [SuppressUnmanagedCodeSecurity] 
    [DllImport("Kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] 
    private static extern bool CopyFileEx(
     string lpExistingFileName, string lpNewFileName, 
     CopyProgressRoutine lpProgressRoutine, 
     IntPtr lpData, ref bool pbCancel, int dwCopyFlags); 
} 

public delegate CopyFileCallbackAction CopyFileCallback(
    FileInfo source, FileInfo destination, object state, 
    long totalFileSize, long totalBytesTransferred); 

public enum CopyFileCallbackAction 
{ 
    Continue = 0, 
    Cancel = 1, 
    Stop = 2, 
    Quiet = 3 
} 

[Flags] 
public enum CopyFileOptions 
{ 
    None = 0x0, 
    FailIfDestinationExists = 0x1, 
    Restartable = 0x2, 
    AllowDecryptedDestination = 0x8, 
    All = FailIfDestinationExists | Restartable | AllowDecryptedDestination 
} 

Hay una more extensive description in MSDN Magazine.

+1

esto podría ser una idea, gracias! mi proceso es una aplicación de consola desencadenada por una tarea programada de Windows en un servidor, por lo que no hay usuario para verla y no necesito comentarios como la barra de progreso o botones para cancelar, pero si esto funciona de todos modos, le dará una tratar. –

+1

Si tiene control sobre lo que está sucediendo, tal vez pueda posponer automáticamente la copia de esos archivos que fueron problemáticos en el primer intento y esperar una hora para volver a intentarlo. –

Cuestiones relacionadas