2012-02-06 5 views
9

J'ai un FileSystemWatcher surveillant un fichier sur un partage réseau. Si un événement se produit pour rendre le partage indisponible, peut-être en raison d'un problème réseau, FileSystemWatcher est déconnecté.FileSystemWatcher Network Disconnect

Évidemment, je peux gérer l'événement "Erreur", peut-être faire de la journalisation et beaucoup d'articles suggèrent de reconnecter le FSW dans le gestionnaire d'événements d'erreur. Mais que se passe-t-il si le partage réseau n'est toujours pas disponible dans l'événement d'erreur? J'ai alors besoin d'introduire une minuterie pour tester si le partage réseau est disponible et essayer de reconnecter le FSW.

1) Y a-t-il une meilleure approche?

2) Y a-t-il une propriété qui me permet de déterminer que le FSW s'est déconnecté du fichier? Je remarque qu'il y a un membre non public de la FSW "stopListening", qui semble être mis à vrai quand le FSW est déconnecté. Mais ce n'est pas exposée publiquement

Toute aide serait appréciée ...

Merci Kevin

+0

double possible de [FileSystemWatcher et déconnexion du réseau?] (Http://stackoverflow.com/questions/281573/filesystemwatcher-and-network-disconnect) –

+0

Merci pour la réponse Erno, mais non ce n'est pas. Je sais que je peux utiliser l'événement Error pour me reconnecter. Mais lorsque l'événement Error est déclenché, que se passe-t-il si le partage réseau est indisponible? À moins d'avoir une sorte de minuterie/tentative de rebranchement, je n'ai aucun autre événement à tenter de me reconnecter! En outre, FSW n'expose pas une propriété publique pour me dire qu'il est déconnecté –

+0

Selon la publication, j'ai suggéré qu'il existe un événement d'erreur que vous pouvez utiliser. Et la minuterie est une bonne idée de sonder la disponibilité. –

Répondre

1

Suivi dans ce. À la suggestion d'une ressource Microsoft sur les forums MSDN, j'ai ajouté cela à Microsoft Connect.

Points clés de la rétroaction de Microsoft: - événement d'erreur est non seulement pour mémoire tampon interne déborde - Ils ajouteront la possibilité d'exposer le stopListening propriété à leur liste de suggestions des clients

lien ici: http://connect.microsoft.com/VisualStudio/feedback/details/727934/filesystemwatcher-error-handling

+0

La page n'est plus disponible ou ne permet pas la lecture - Rend la réponse sans valeur :( – Darren

7

quelques commentaires et suggestions ... (qui a grandi et a grandi comme je tapais ... désolé)

L'événement FileSystemWatcher.Error est déclenché lorsque FileSystemWatcher reçoit tellement d'événements si rapidement qu'il ne peut pas les gérer tous. Il n'est pas se déclencher lorsqu'une erreur se produit dans l'observation du système de fichiers (tel que le décrochage du réseau).

Je crois que j'ai eu une situation similaire. Le problème est que lorsque la connexion réseau est coupée, le FileSystemWatcher ne déclenche jamais un événement, car il ne peut pas réellement voir ce qu'il est censé regarder, mais il ne semble pas en être conscient. Lorsque la connexion réseau revient, le FileSystemWatcher ne récupère pas, c'est-à-dire qu'il ne peut toujours pas voir la connexion (restaurée). La seule solution que nous ayons trouvée qui semblait fonctionner de manière fiable était d'avoir une minuterie qui supprimait régulièrement tout l'objet FileSystemWatcher et en créait un nouveau, définissant tous les événements et le dossier de surveillance, etc. Depuis la suppression et la création d'un nouveau FileSystemWatcher est (relativement) rapide (c.-à-d. en millisecondes), vous pouvez régler le minuteur pour qu'il s'activer toutes les 10 secondes sans trop utiliser le processeur. Bien sûr, si le réseau est toujours éteint, FileSystemWatcher ne pourra pas voir le réseau, peu importe ce que vous faites. Mais c'est OK, il va essayer à nouveau dans 10 secondes.

Deux choses à surveiller avec cette solution:

  1. Lorsque la minuterie active, il faut vérifier que le FileSystemWatcher ne traite pas actuellement des événements, et il faut attendre si elle est. Ainsi, dans l'événement timer, arrêtez le Timer, arrêtez FileSystemWatcher d'élever des événements, puis attendez que les événements FileSystemWatcher se terminent (en utilisant lock (...) {...} est un bon moyen de le faire).
  2. Après avoir déposé et recréé le FileSystemWatcher, vous devez vérifier manuellement tous les événements qui se sont produits lors de l'actualisation de FileSystemWatcher (ou lorsque le réseau était arrêté). Par exemple, si vous regardez des fichiers en cours de création et qu'un fichier est créé lors de l'actualisation de FileSystemWatcher ou de la fermeture de la connexion réseau, vous n'obtiendrez pas d'événements pour ces fichiers lorsque vous démarrez la nouvelle instance de FileSystemWatcher (puisque les fichiers ont déjà été créés).

J'espère que cela aide.

+0

Merci pour la réponse Mark. Après avoir relu le document MSDN, je vois que vous avez raison, l'événement d'erreur ne se déclenche pas réellement quand une erreur survient dans le système de fichiers, ce qui était une mauvaise compréhension de ma part. –

+1

Votre approche est intéressante, cependant (probablement en raison d'une faille de conception), le FileSystemWatcher est en réalité statique dans un service WCF à haut volume. Ainsi, le concept d'avoir à le réinitialiser toutes les 10 secondes n'est probablement pas une option pour nous, même un léger coup de performance pourrait être coûteux pour nos temps de réponse requis. Il semble qu'il n'y ait pas de réponse, puisque nous ne pouvons absolument pas compter sur l'événement d'erreur, la solution optimale serait de ré-factoriser notre solution pour supprimer le FileSystemWatcher puisqu'il semble être une approche peu fiable. –

0

Quelque chose comme ça ne fonctionnerait pas? Semble fonctionner pour mon cas de test simple.

var fsw = new FileSystemWatcher("[folder]", "*.*") { IncludeSubdirectories = true}; 
var fsw_processing = false; 
fsw.Deleted += (s, e) => 
{ 
    fsw_processing = true; 
    fsw.EnableRaisingEvents = false; 
    //...... 
    fsw.EnableRaisingEvents = true; 
    fsw_processing = false; 
};  
fsw.Changed += (s, e) => 
{ 
    fsw_processing = true; 
    fsw.EnableRaisingEvents = false; 
    //...... 
    fsw.EnableRaisingEvents = true; 
    fsw_processing = false; 
};  
//governor thread to check FileSystemWatcher is still connected. 
//It seems to disconnects on network outages etc. 
Task.Run(() => 
{ 
    while (true) 
    { 
     if (fsw.EnableRaisingEvents == false && fsw_processing == false) 
     {       
      try 
      {fsw.EnableRaisingEvents = true;} 
      catch (Exception) { fsw.EnableRaisingEvents = false; }    
     } 
     System.Threading.Thread.Sleep(1000 * 10);//sleep 10 secs 
    } 
});