2009-11-15 3 views
1

je fais une opération sur le fichier « grand » (environ 4 Mo)Winforms: éviter l'application gel

-je faire ceci: 1. obtenir tous les fichiers d'un répertoire et placez-les dans un IList MyInfoClass a des propriétés: nom, extension, fullPath, creationDate, contentPart 2. Je fais une requête Linq pour obtenir seulement un type d'extension. 3. Je boucle sur le résultat de la requête Linq et pour chacun, j'ouvre le fichier, je fais une opération (valeur) et je place le résultat dans MyFileIno.ContentPart.

Pour votre information: 30 fichiers, il est une opération de 14sec

C'est un travail. Le problème, lorsque je cours ma bibliothèque à partir de l'interface utilisateur, lorsque je clique sur le bouton, la fenêtre se fige pendant le temps de fonctionnement. Je voudrais:

  1. une solution pour ne pas geler la forme
  2. voir l'opération de progression

Pourriez-vous me donner la meilleure pratique pour résoudre ce genre de problème?

Merci,

code

public class FileManager 
{ 
    public string CurrentFileName { get; set; } 
    public void Validation(string path) 
    { 
     IList<InfoFile> listFile = GetListFile(path); 
     foreach (InfoFile item in listFile) 
     { 
      CurrentFileName = item.Name; 
      ..... 
     } 
    } 
} 


private void button1_Click(object sender, EventArgs e) 
{ 
    var worker = new BackgroundWorker(); 
    worker.DoWork += (s, args) => 
    { 
     int percentProgress = 6; 
     FileManager fileManager = new FileManager(); 
     fileManager.Validation(@"C:....."); 
     ((BackgroundWorker)s).ReportProgress(percentProgress, fileManager.CurrentFileName); 
    }; 

    worker.ProgressChanged += (s, args) => 
    { 
     var currentFilename = (string)args.UserState; 
     label1.Text = currentFilename; 
     progressBar1.Value = args.ProgressPercentage; 
    }; 

    worker.RunWorkerCompleted += (s, args) => 
    { 
     progressBar1.Value = 0; 
    }; 
    worker.RunWorkerAsync(); 
} 

Répondre

15

L'application se bloque parce que vous exécutez le fichier d'analyse syntaxique le thread principal. Vous pouvez utiliser BackgroundWorker pour effectuer une opération sur un nouveau thread. Voici un pseudo code qui pourrait vous aider à démarrer:

private void button1_Click(object sender, EventArgs e) 
{ 
    var worker = new BackgroundWorker(); 
    worker.DoWork += (s, args) => 
    { 
     // Here you perform the operation and report progress: 
     int percentProgress = ... 
     string currentFilename = ... 
     ((BackgroundWorker)s).ReportProgress(percentProgress, currentFilename); 
     // Remark: Don't modify the GUI here because this runs on a different thread 
    }; 
    worker.ProgressChanged += (s, args) => 
    { 
     var currentFilename = (string)args.UserState; 
     // TODO: show the current filename somewhere on the UI and update progress 
     progressBar1.Value = args.ProgressPercentage; 
    }; 
    worker.RunWorkerCompleted += (s, args) => 
    { 
     // Remark: This runs when the DoWork method completes or throws an exception 
     // If args.Error != null report to user that something went wrong 
     progressBar1.Value = 0; 
    }; 
    worker.RunWorkerAsync(); 
} 
+0

Merci. Bonnes remarques sur l'interface graphique, j'ai l'exception ... :) Au lieu de percentProgress, je voudrais avoir le nom du fichier en traitement et pourquoi pas le pourcentage? –

+0

Vous pouvez utiliser 'BackgroundWorker.ReportProgress (int, object)' où le deuxième argument est un objet d'état utilisateur personnalisé que vous pouvez utiliser dans le rappel 'ProgressChanged' par l'intermédiaire de' args.UserState'. –

+0

J'ai mis à jour ma réponse pour en tenir compte. –

Questions connexes