2012-08-08 21 views
6

Wir haben einen NetApp NAS-Filer, der von Zeit zu Zeit zu versagen scheint, nicht sicher, ob dies von Netzwerkproblemen, hoher Auslastung oder dem Filer selbst abhängt; Die Sache ist, dass der übliche System.IO.File.Copy(...) Befehl manchmal unerwartet fehlschlägt, während es eine Minute zuvor funktionierte und wieder eine Minute nach ... filer arbeitet mit dem CIFS-Dateisystem.Sicheres Kopieren von Dateien auf NAS Filer

in meinem Log4Net Logfiles sehe ich die Ausnahme:

System.IO.IOException: Der angegebene Netzwerkname ist nicht mehr verfügbar. bei System.IO .__ Error.WinIOError (Int32 Errorcode, String maybeFullPath) ...

Netzwerk-Team ist sich nicht sicher, was passiert und warum, denke ich jetzt, wenn ich eine einfache try/Wiederholungssystem implementieren kopieren die Datei und die Kopie im Falle eines Fehlers erneut versuchen, könnte es sein, dass System.IO.File.Copy nicht für CIFS-Speicher, sondern für normale NTFS-Laufwerke oder stabilen Netzwerkspeicher entwickelt wurde.

Gibt es gemeinsame Muster oder .NET-Klassen geeignet, um dies zu tun kopieren und wiederholen oder soll ich einfach einen Ansatz wie in der folgenden Pseudo-Code verwenden?

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()' läuft auf die Funktion Win32 ['CopyFile'] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363851.aspx) herunter . Also würde ich etwas kodieren, das das wiederholt benutzt und sehen, ob es auch fehlschlägt. Ich denke, du versuchst, ein Software-Pflaster auf ein größeres Problem zu stellen. –

+1

Richten Sie einen 'ping -t hostname' ein und protokollieren Sie ihn in einer Datei. Lassen Sie es für ein paar Stunden laufen und dann nach Timeouts suchen. Das sollte Ihnen sagen, ob das Problem netzwerkbezogen ist. Könnte immer noch ein Problem mit dem Gerät selbst sein, aber zumindest kann man ein .NET-Problem ausschließen. –

+0

Ich mag diese Schleife. Möglich ist eine kleine Wartezeit im Fangen. – Paparazzi

Antwort

1

nach Wochen und Wochen der Forschung, Tests und Schmerzen habe ich endlich eine funktionierende Lösung gefunden, beschlossen, die System.IO.File.Copy Methode mit Aufruf von Microsoft Robocopy command zu ersetzen, die in Win Server 2008 R2 verfügbar ist und schien von Anfang an gut zu funktionieren Versuchen. Das macht es mir angenehm, dass ich das Rad nicht neu erfinde, sondern eine erprobte Technologie verwende, die genau auf meine Bedürfnisse zugeschnitten ist. Vielen Dank für Ihre Antworten und Kommentare.

2

Das gleiche hapens zu mir. Ich habe eine alte NAS Server und von Zeit zu Zeit Windows shows an error telling me that the drive is not accessible anymore.
Zur Verwaltung der file copy process vielleicht könnten Sie stattdessen CopyFileEx (von Windows API) verwenden, wie in der nächsten Probe gezeigt:

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 
} 

Es gibt eine more extensive description in MSDN Magazine.

+1

das könnte eine idee sein, danke! Mein Prozess ist eine Konsolenanwendung, die von einem Windows-Task auf einem Server ausgelöst wird, so dass kein Benutzer sie sehen kann und ich brauche kein Feedback wie Fortschrittsbalken oder Abbrechen-Buttons, aber es funktioniert sowieso umso besser, wird es geben Versuchen. –

+1

Wenn Sie die Kontrolle darüber haben, was passiert, können Sie möglicherweise die Kopie der Dateien, die beim ersten Versuch problematisch waren, automatisch verschieben und eine Stunde warten, bis Sie es erneut versuchen. –