2012-01-06 21 views
11

Piszę rozwiązanie, w którym używam niektórych plików konfiguracyjnych, które powinny być edytowalne w środowisku wykonawczym. Używałem w tym celu FileSystemWatcher i nigdy nie miałem z nim problemów, ale teraz powoduje to CTD w przypadku zmiany nazwy.FileSystemWatcher powoduje awarię na pulpicie

To (bezużyteczny) fragment kodu będzie odtworzyć problem w mojej konfiguracji:

private static int _s_renamed; 
private static int _s_created; 
private static int _s_errors; 

private static void monitorConfiguration(string configRootFolder) 
{ 
    var fsw = new FileSystemWatcher(configRootFolder, ConfigFilePattern) 
    { 
     NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName, 
     IncludeSubdirectories = false 
    }; 
    fsw.Renamed += (sender, args) => ++_s_renamed; // <-- ! CTD efter this one ! 
    fsw.Created += (sender, args) => ++_s_created; 
    fsw.Error += (sender, args) => ++_s_errors; 
    fsw.EnableRaisingEvents = true; 
} 

Katastrofa pochodzi z FileSystemWatcher się wydaje. Jeśli ustawię punkt przerwania w module obsługi zdarzeń dla FileSystemWatcher.Renamed, zostanie on trafiony, ale aplikacja ulega awarii, gdy się z niego wycofam. Jeśli ustawię punkt przerwania w obsłudze zdarzeń FileSystemWatcher.Created, tak się nie stanie.

Wszelkie sugestie?


EDIT 1: biegnę .NET 4 na Windows 7 x64 (Ostateczny) platforma Widziałem kilka dyskusji dotyczących tego typu problemów, ale wszystko zostało związane z ludzi, którzy próbują zaktualizować UI rzeczy (które musi być wykonane z wątku głównego/UI) z procedur obsługi zdarzeń. Właśnie dlatego próbuję zwiększyć liczbę liczników w kodzie eksperymentalnym.

+2

Czy istnieje wyjątek? – David

+0

Nie, aplikacja ulega awarii na pulpicie i wygląda na to, że nie mogę jej złapać. Jest to aplikacja WPF i przechwytywanie wszystkich nieobsługiwanych wyjątków (Application.DispatcherUnhandledException), ale ten nie został złapany. –

+0

Co to jest CTD i co robi? – Gabe

Odpowiedz

1

prostu do wyjaśnienia:

Problemem było miałem więcej/starszych konsumentów o FileSystemWatcher gdzie indziej w moim systemie i jeden z nich spowodowała nieobsługiwany wyjątek. Problem polega na tym, że wyjątek zostanie zgłoszony w zupełnie innym wątku i spowodował awarię aplikacji na pulpicie. Moment nabrał mnie na myśl, że to mój nowy konsument, który w jakiś sposób powoduje, że isse, ale kiedy poszedłem za radą Chrisa Shaina (patrz komentarze w pytaniu), aby włączyć łamanie wyjątków (msdn.microsoft.com/en-us/library/d14azbfh.aspx) Natychmiast znalazłem prawdziwego winowajcę.

Wolałbym przyznać Chrisowi rozwiązanie, ale nigdy nie opublikował ponownie, więc jest.Mam nadzieję, że czegoś się nauczyliśmy.

Dzięki wszystkim i szczęśliwy kodowania

/Jonas

0

może być uruchomiony na każdym z tych trzech sytuacji

  1. Przekazany w katalogu nie istnieje, a plik nie został znaleziony IO jest wyrzucane.
  2. Przekazany katalog jest prawidłowy, ale proces, w którym go uruchomiono, nie ma praw dostępu
  3. Argumenty (nadawca, argumenty) przekazywane jako dane, jeden może być pusty i twój kod (ponieważ jest to przykład i możemy " t zobacz prawdziwy kod) nie radzi sobie z wartością zerową i wyrzuca błąd.
0

W .NET należy zsynchronizować wątek wygenerowany przez FileSystemWatcher z wątkiem interfejsu użytkownika. W tym celu formanty interfejsu użytkownika mają metodę: myControl.Invoke (...) dla tego efektu. Każdy inny sposób próbować zsynchronizować będzie mieć pewne losowe efekty jak ścina wyjątki itp

zobaczyć tutaj: http://msdn.microsoft.com/en-us/magazine/cc300429.aspx http://weblogs.asp.net/justin_rogers/pages/126345.aspx

nadzieję, że pomoże

0

Może plik lub obiekt są w użyciu, miałem podobny problem i rozwiązać go za pomocą następującego kodu

private void InitWatch() 
{ 
    FileSystemWatcher watcher = new FileSystemWatcher(); 
    watcher.Path = @"C:\LoQueSea"; 
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
    | NotifyFilters.FileName | NotifyFilters.DirectoryName; 
    watcher.Filter = "*.*"; 
    watcher.Created += new FileSystemEventHandler(OnCreated); 
    watcher.EnableRaisingEvents = true; 
} 
private void OnCreated() 
{ 
    try 
    { 
     if (!myObjectToPrint.Dispatcher.CheckAccess()) 
     { 
      myObjectToPrint.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, 
       new Action(
        delegate() 
        { 
        //your code here... 
        } 
        ) 
     } 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    }   
} 

sALUDOS ..

+0

Dlaczego, na Boga, próbujesz {} catch (Exception ex) {throw ex; } '? Nie ma to absolutnie nic wspólnego z niszczeniem śladu stosu, co powoduje, że awarie są trudniejsze do debugowania. – tomfanning

+0

Nie wydaje się również, aby miało to związek z problemem zgłaszanym przez OP (nieobsłużony wyjątek w FileSystemWatcher po zwolnieniu zdarzenia Renamed). – tomfanning

+0

Tego rodzaju pozornie bezsensowna próba ... catch może być przydatna do celów debugowania. Umieszczenie punktu przerwania na "throw ex" daje możliwość sprawdzenia, co się dzieje, gdy próbujesz rozwiązać nieoczekiwany wyjątek. Powinien zostać usunięty, gdy skończysz, oczywiście. –