Question

Récemment décidé d'écrire une fenêtre « rapide » forme app pour marquer mes fichiers MP3. Pas fait quoi que ce soit avec le parallélisme depuis .Net 3.0, donc je suis à la recherche à la méthode Parallel.ForEach pour faire face à l'interface de verrouillage que je reçois quand j'utilise une déclaration standard foreach. Voici un extrait:

var i = 1;
var files = new List<string>(); // File list is populated using recursive method.

foreach(var f in files) {
    // Add a row
    var row = dgvList.Rows[dgvList.Rows.Add()];

    // Update label
    lblSummary.Text = string.Concat("Processing... ", i);
    // Do things with row

    // Increment progress bar
    progressBar.PerformStep();
    i++;
}

J'ai compris l'utilisation simple Parallel.ForEach (), mais je ne suis pas sûr que je devrais utiliser cette méthode particulière de mettre à jour l'interface utilisateur? Toutes les suggestions?

Était-ce utile?

La solution 3

OK, j'ai trouvé la meilleure façon d'y parvenir est en exécutant quelque chose comme ceci:

// Kick off thread
Task.Factory.StartNew(delegate{
     foreach(var x in files) {
         // Do stuff

         // Update calling thread's UI
         Invoke((Action)(() => {
              progressBar.PerformStep();
         }));
     }
}

En fait, je mis à jour mon code pour remplir une liste dans la boucle foreach, puis attribuez-lui que la daragrid via .DataSource, au lieu de travailler avec la collection .Rows directement. Aurait dû le faire dès le départ vraiment:)

Autres conseils

Vous ne devriez pas utiliser les bibliothèques parallèles de votre thread d'interface utilisateur. La bibliothèque parallèle gère un groupe de tâches sur plusieurs threads de sorte que vous ne devriez pas écrire aucun code de l'interface utilisateur à l'intérieur.

Ce que vous devez faire est de déplacer votre logique métier à des tâches d'arrière-plan et mettre à jour l'interface utilisateur à l'aide dispatcher qui exécutera sur l'interface utilisateur fil

MSDN dit

It is important to keep your application's user interface (UI) responsive. If an 
operation contains enough work to warrant parallelization, then it likely should not
be run that operation on the UI thread. Instead, it should offload that operation to 
be run on a background thread. For example, if you want to use a parallel loop to 
compute some data that should then be rendered into a UI control, you should consider
executing the loop within a task instance rather than directly in a UI event handler. 
Only when the core computation has completed should you then marshal the UI update back 
to the UI thread.

et surtout si vous essayez de mettre à jour l'interface utilisateur de fil Paralle.Foreach

If you do run parallel loops on the UI thread, be careful to avoid updating UI 
controls from within the loop. Attempting to update UI controls from within a parallel 
loop that is executing on the UI thread can lead to state corruption, exceptions, 
delayed updates, and even deadlocks, depending on how the UI update is invoked

Vous devriez être très prudent avec filet de sécurité. Vous devriez être assurez-vous de verrouiller un objet que vous utilisez, et déverrouiller de façon appropriée.

Dans le cas contraire, il ne devrait y avoir aucun problème, je sais d'utiliser Parallel.ForEach pour l'interface utilisateur.

EDIT: vous pouvez définir Form.CheckForIllegalCrossThreadCalls = false pour désactiver pour vérifier la sécurité des threads
. Voici quelques documents: http://msdn.microsoft .com / fr-fr / bibliothèque / system.windows.forms.control.checkforillegalcrossthreadcalls.aspx
Cela fonctionne, mais il est dangereux, parce que vous devez prendre soin de votre fil de sécurité par vous-même.

Une meilleure façon de traiter ce problème est d'utiliser le Invoke-modèle pour la logique de l'interface utilisateur, mais le parallélisme souffrira, comme l'opération de l'interface utilisateur lui-même sera appelé sur le thread d'interface utilisateur.
Il est, cependant, le moyen sûr de faire les choses.
Documentation: http://msdn.microsoft.com/en-us/library/ms171728 .aspx

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top