2010-03-01 12 views
1

Bonjour J'ai recommencé à rencontrer un problème que je n'arrive pas à résoudre seul.C# Limite du nombre de boîtes à messages

J'ai un FileSystemWatcher nommé filOvervakare et utilise ce code pour déclencher une méthode.

filOvervakare.NotifyFilter = NotifyFilters.Size; 
filOvervakare.NotifyFilter = NotifyFilters.LastWrite; 

filOvervakare.Changed += new FileSystemEventHandler(filOvervakare_Changed); 

Ceci est la méthode:

void filOvervakare_Changed(object sender, FileSystemEventArgs e) 
{ 
    if (MessageBox.Show("Vill du ladda upp filen " + e.Name + "?", "En fil har ändrats", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) 
    { 
     //code code code   
    } 
} 

A chaque fois qu'un fichier est modifié, il est censé montrer une fois que le messagebox. Le problème est qu'au lieu d'avoir une boîte de message, il apparaît comme 5-6 d'entre eux et je n'ai aucune idée de comment résoudre ce problème et j'espère que certains d'entre vous pourraient avoir une bonne solution. :)

Merci!

// Morgan

Répondre

1

Vous pouvez utiliser un booléen pour vous dire si vous avez une boîte de message ouvert.

private bool messageBoxIsOpen; 

void filOvervakare_Changed(object sender, FileSystemEventArgs e) 
{ 
    if (this.messageBoxIsOpen) 
    { 
     return; 
    } 

    this.messageBoxIsOpen = true; 
    if (MessageBox.Show(
     "Vill du ladda upp filen " + e.Name + "?", 
     "En fil har ändrats", 
     MessageBoxButtons.YesNo, 
     MessageBoxIcon.Question) == DialogResult.Yes) 
    { 
     //code code code   
    } 

    this.messageBoxIsOpen = false; 
} 
2

Cela est dû au fait que le gestionnaire d'événements est appelé sur un thread différent pour chaque notification. Une solution rapide est de définir la propriété FileSystemWatcher.SynchronizingObject:

public Form1() { 
     InitializeComponent(); 
     fileSystemWatcher1.SynchronizingObject = this; 
    } 

Mais ce n'est pas vraiment une bonne idée, le FSW est susceptible de manquer des notifications, car il est bloqué, vous attend de cliquer sur le bouton OK. L'affichage d'une boîte de message dans l'événement de notification n'est pas une bonne idée, vous voulez traiter les notifications le plus rapidement possible.

+0

@nobugz: ** le gestionnaire d'événements est appelé sur un thread différent pour chaque notification ** nécessite une citation s'il vous plaît. –

+0

@sameh: 6 boîtes à messages ne sont-elles pas suffisamment prouvées? –

0

La meilleure façon de résoudre ce problème est de déclarer un bool privé, comme ceci:

private bool m_IsBoxShown; 

Dans votre constructeur, définissez la valeur false. Modifiez votre code ci-dessus pour lire comme ceci: vide filOvervakare_Changed (expéditeur d'objet, FileSystemEventArgs e)
{
if (m_IsBoxShown == false) { m_IsBoxShown = true; si (MessageBox.Show ("Vill du ladda UPP fichiern" + e.Name + "?", "En fil har ändrats", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
m_IsBoxShown = faux; // code code
} else {m_IsBoxShown = false; }} }

1

Il y a quelques événements, quelque chose comme LastAccess, etc LastWrite que le veilleur de système de fichiers déclenche des événements sur. Vous pouvez vérifier les arguments de l'événement pour savoir pourquoi l'événement a été déclenché avant d'afficher la boîte de message ou définir la propriété NotifyFilter.

0

Ce que je recommanderais est d'avoir un court délai, disons 10-100ms avant d'afficher le MessageBox. De cette façon, quand un fichier change plusieurs fois très rapidement, vous obtenez seulement un MessageBox. En d'autres termes, lorsqu'une notification arrive, démarrez la minuterie. Si la minuterie est déjà démarrée, ignorez la notification. Lorsque la minuterie se déclenche, arrêtez la minuterie et affichez le MessageBox.

1

Vous pouvez enregistrer le dernier nom de fichier modifié dans une variable fictive, et lorsque l'événement modifié est déclenché, n'affichez pas la boîte de message sauf si le nom de fichier est différent de la variable enregistrée.

string lastChangedFileName = ""; 
void filOvervakare_Changed(object sender, FileSystemEventArgs e) 
    { 

if(lastChangedFileName != e.Name) 
{ 
     if (MessageBox.Show("Vill du ladda upp filen " + e.Name + "?", "En fil har ändrats", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) 
     { 
      //code code code   
     } 
} 
lastChangedFileName = e.Name; 

    } 
+0

Merci c'était la solution la plus simple! Et merci à tous les autres pour une réponse quck avec différentes façons de réduire mon problème! // Morgan – warbio

+1

Ne faut-il pas 'lastChangedFileName = e.Name;' être dans l'instruction 'if' avant d'afficher la boîte de message? Sinon, 'lastChangedFileName' ne sera défini qu'après la fermeture de la boîte de message, et il sera défini * à chaque fois que l'événement est déclenché. –

+0

+1: Merci Zach, tu as raison ;-) –