2011-11-21 8 views
5

Mam problem z działaniem na system plików, co doprowadza mnie do szału.. Plik FileSystemWatcher ulega awarii podczas zgłaszania wyjątku, plik throws jest używany dla przyszłych plików.

Okazuje się, że patrzę na nowych plików tekstowych w folderze, kiedy utworzono zdarzenie jest wywoływane, ja po prostu czytać to za pomocą następującego kodu:

string txtTemp = File.ReadAllText(MyFilePath); 

potem przetwarzać dane w txtTemp ciąg, w zasadzie czytam to linie & przechowywać dane na DB, całkiem proste, prawda?

Problem jest, gdy wyjątek jest podniesione w tym procesie (powiedzmy połączenie db nie powiodło się), to nie ma znaczenia, czy ja go złapać, bo przez następne najbliższych plików aplikacja wygeneruje wyjątek mówiący

"Proces nie może uzyskać dostępu do pliku" theNewComingFile.txt ", ponieważ jest to używane przez inny proces."

Dlaczego nowy utworzony plik może być używany, jeśli nie został jeszcze otwarty lub odczytany? A aplikacja ciągle rzuca ten "proces nie ma dostępu do pliku" wyjątek dla wszystkich nowych plików.

Jedyną rzeczą, jaką możemy zrobić, to zamknąć i ponownie otworzyć aplikację, to resetuje aplikację i wszystko działa dobrze, dopóki znowu wyjątek jakiegokolwiek rodzaju jest wskrzeszeni> (ojej!)

Jakieś pomysły? jakiekolwiek obejście? jakieś pomysły? jakieś sugestie ... cokolwiek? hehehehe =)

Dzięki, kolesie !!

+0

Czy możliwe jest skonfigurowanie innego FileSystemWatchera w przypadku wyjątku i obaj ścigają się z tym samym plikiem? Czy mógłbyś opublikować swój kod obsługi zdarzenia, a także kod instalacyjny FileSystemWatcher? – zmbq

+0

Więcej kodu byłoby pomocne – jtm001

+0

['File.ReadAllText()'] (http://msdn.microsoft.com/en-us/library/ms143368.aspx): "Otwiera plik tekstowy, odczytuje wszystkie wiersze pliku , **, a następnie zamyka plik **. ". Nie powinno to nastąpić, dopóki wyjątek nie zostanie podniesiony z tego miejsca. Nie możesz wypróbować StreamReadera, aby przeczytać plik? – CodeCaster

Odpowiedz

5

możesz rozpocząć śledztwo, korzystając z numeru Sysinternals Process Explorer. Daje ci więcej szczegółów, szczególnie na temat tego, który proces przechowuje plik.

+0

To nie była odpowiedź, ale było tak pomocne, że dałem to na dobre :-D –

-1

Obejście problemu jest proste - umieść obserwatora we własnej aplikacji AppDomain, odrzuć AppDomain i uruchom ponownie, jeśli poradzisz sobie z wyjątkiem. To najprawdopodobniej naprawi twój problem. Ale dlaczego tak się dzieje? Będę musiał trochę o tym pomyśleć i może coś znaleźć.

+3

Załóżmy łódź w naszej łodzi, gdy nasza łódź tonie. A co, jeśli druga łódź zatonie? Wrzuć kolejną łódź! – CodeCaster

+0

hahaha yeah right dude! –

+0

Nazywają się one łodziami ratunkowymi. Każdy statek ma je na wypadek, gdyby statek tonął. W każdym razie ... jeśli FileSystemWatcher jest krytycznie wadliwy, wtedy ta sugestia może być uzasadnioną opcją. Powiedziawszy to, izolacja prawdopodobnie nie jest potrzebna, ponieważ problem jest po prostu uchwytem otwartego pliku. – Triynko

2

Utworzone zdarzenie jest uruchamiane przed ukończeniem zapisywania pliku.

Od MSDN:

OnCreated zdarzenie jest wywoływane, gdy tylko zostanie utworzony plik. Jeśli plik jest kopiowany lub przesyłany do obserwowanego katalogu, zdarzenie OnCreated zostanie natychmiast podniesione, a następnie nastąpi jedno lub więcej zdarzeń OnChanged .

Tak więc opisanie wyjątku byłoby dość normalne. Kiedy mam do czynienia z tą sytuacją, najpierw testuję plik, aby sprawdzić, czy mogę uzyskać do niego dostęp, czy nie. Oto funkcja, której używam:

private static bool GetExclusiveAccess(string filePath) 
    { 
    try 
    { 
     using (FileStream file = new FileStream(filePath, FileMode.Append, FileAccess.Write)) 
     { 
      file.Close(); 
      return true; 
     } 
    } 
    catch (IOException) 
    { 
     return false; 
    } 
    } 

Jeśli nie masz dostępu, musisz poczekać i sprawdzić ponownie.

+0

Nop, nie radzę sobie z plikiem, jest on tworzony z innej aplikacji, ale załóżmy, że to był problem, dlaczego jeśli uruchomię go ponownie po wyjściu, to działa dobrze? –

+0

Nie ma to związku z kopiowaniem pliku. Każdy plik, który powstaje jako pierwszy, musi zostać utworzony, a następnie "wypełniony" treścią, a następnie zamknięty. Wszystko podczas "wypełniania" jest zablokowane przez twórcę pliku. Ale FileSystemWatcher uruchamia zdarzenie OnCreated zaraz po utworzeniu. Masz więc wyścig pomiędzy twórcą pliku a kodem odpowiadającym zdarzeniu OnCreated. Jeśli jest to bardzo mały plik, wypełnienie może zostać wykonane do czasu, w którym wątek uzyska wartość OnCreated. Ale zwykle zobaczysz, co opisałeś. Twórca plików wciąż "wypełnia" to. –

+0

Dzięki Russell McClure, przetestuję to dzisiaj i spróbuję wdrożyć twoje rozwiązanie, a potem dam ci znać. Dzięki jeszcze raz ! –

2

Może to być czynność otwierania pliku zmienia ostatni znacznik czasu: może to spowodować pętlę.

Może zajść potrzeba zmiany projektu, aby zdarzenia zostały umieszczone w kolejce, jeśli (i tylko jeśli) plik nie jest już w kolejce do przetworzenia. Następnie możesz pułapkę na wyjątki itp., Pod odpowiednią kontrolą w drugiej nici, bez wchodzenia w drogę Obserwatora.

[W przeszłości widziałem bardzo ciekawe narożne przypadki z FileSystemWatcher - może to być trochę bestia, gdy zostanie przyparty do muru. Jeden (jakiś czas temu) spowodował, że w systemie Windows Server 2003 zawieszał się niezupełnie powtarzalny niebieski ekran, gdy przepełnił się wewnętrzny bufor, ponieważ był zalewany zdarzeniami. Najlepiej bądź ostrożny.]

Powiązane problemy