c # - Fileksistens check efter en omdøbning af en mappe returnerer en forkert værdi på UNC-del

Indlæg af Hanne Mølgaard Plasc

Problem



På en Windows 7-boks (eller server) har vi en mappe på en UNC-del (cross machine UNC, ikke lokalhost). Vi omdøber den pågældende mappe, og derefter kontrollerer eksistensen af ​​en fil på den nye mappeplacering. Selv om det eksisterer, tager det næsten 5 sekunder for File.Exists at returnere sandt på den.


Fuld repro findes på https://github.com/davidebbo/NpmFolderRenameIssue. Her er kernekoden: [5]


// This file doesn't exist yet
// Note that the presence of this existence check is what triggers the bug below!!
Console.WriteLine("Exists (should be false): " + File.Exists("test/test2/myfile"));

// Create a directory, with a file in it
Directory.CreateDirectory("test/subdir/test");
File.WriteAllText("test/subdir/test/myfile", "Hello");

// Rename the directory
Directory.Move("test/subdir/test", "test/test2");

var start = DateTime.UtcNow;

// List the files at the new location. Here, our file shows up fine
foreach (var path in Directory.GetFiles("test/test2"))
{
    Console.WriteLine(path);
}

for (; ; )
{
    // Now do a simple existence test. It should also be true, but when
    // running on a (cross machine) UNC share, it takes almost 5 seconds to become true!
    if (File.Exists("test/test2/myfile")) break;

    Console.WriteLine("After {0} milliseconds, test/test2/myfile doesn't show as existing",
        (DateTime.UtcNow - start).TotalMilliseconds);
    Thread.Sleep(100);
}

Console.WriteLine("After {0} milliseconds, test/test2/myfile correctly shows as existing!",
    (DateTime.UtcNow - start).TotalMilliseconds);


Så det ser ud til, at den oprindelige eksistenscheck forårsager eksistensværdien at blive cachelagret og forårsager denne falske adfærd.


Spørgsmål : Hvad er forklaringen til dette? Hvad er den bedste måde at undgå det på?


BEMÆRK : Dette problem opstod først, når du bruger npm (Node Package Manager) på Windows. Koden jeg har her er en C # port af repro. Se https://github.com/isaacs/npm/issues/2230 for det originale Node/npm problem. Målet er at finde en måde at løse det på. [6]

Bedste reference


David,
Omdirigeringsprogrammet implementerer en negativ 'Fil ikke fundet' cache, som forhindrer en klient i at oversvømme en server med ikke fundet forespørgsler. Standardbuffetiden er 5 sekunder, men du kan ændre registreringsværdien FileNotFoundCacheLifetime for at styre cachen eller deaktivere den ved at indstille denne værdi til 0.


Detaljer: http://technet.microsoft.com/en-us/library/ff686200(v=WS.10).aspx[7]

Andre referencer 1


Der er flere niveauer af caching i netværkskode. Dette kan bremse den tid, filens eksistens endelig viser sig.


En løsning ville ikke være at bruge filaktier, men skabe en simpel klient/server arkitektur, hvor serveren returnerer fileksistensen fra det lokale filsystem. Det burde virkelig fremskynde vare detektionstider.


Mit gæt ville være, at hvis du forsøgte at åbne filen, selvom File.Exists siger, at den ikke eksisterer, skal den åbnes korrekt, så du kan bruge servereksistensoplysningerne. Hvis det ikke virker, kan du blot tilføje en download mulighed for server/klient arkitektur.

Andre referencer 2


Når jeg vidste om 'Filen ikke fundet' cachen, kunne jeg løse problemet ved at bruge et FileInfo objekt, som implementerer en Refresh() metode. Din kode kan gøre dette i stedet:


FileInfo testFile = new FileInfo("test/test2/myfile");
Console.WriteLine("Exists (should be false): " + testFile .Exists);
Directory.Move("test/subdir/test", "test/test2");
testFile.Refresh();

// the FileInfo object should now be refreshed, and a second call to Exists will return a valid value
if (testFile.Exists)
{
    ...
}