Prise en charge des rapports d'avancement et des résultats supplémentaires dans .NET 4.0 « Bibliothèque parallèle de tâches »

StackOverflow https://stackoverflow.com/questions/1535749

Question

Je sais que Tâche parallèle Bibliothèque est encore en version bêta et il y a probablement moins de ressources disponibles, mais de tout ce que j'ai lu, bibliothèque donne un traitement très spécial d'ordonnancement des tâches, la gestion des exceptions et annulation .

Mais je ne trouve pas de références à les rapports d'étape et envoi des résultats supplémentaires des tâches. Ces 2 choses semblent trop importantes pour ne pas tenir compte. Pouvez-vous jeter un peu de lumière sur la façon de gérer ces tâches dans la bibliothèque parallèle ou consultez quelques articles qui les explique?

Était-ce utile?

La solution

Cet exemple met à jour une barre de progression:

using System;   
using System.Threading;   
using System.Threading.Tasks;   
using System.Windows.Forms;   

class SimpleProgressBar : Form   
{   
    [STAThread]   
    static void Main(string[] args)   
    {   
        Application.EnableVisualStyles();   
        Application.Run(new SimpleProgressBar());   
    }   

    protected override void OnLoad(EventArgs e)   
    {   
        base.OnLoad(e);   

        int iterations = 100;   

        ProgressBar pb = new ProgressBar();   
        pb.Maximum = iterations;   
        pb.Dock = DockStyle.Fill;   
        Controls.Add(pb);   

        Task.ContinueWith(delegate   
        {   
            Parallel.For(0, iterations, i =>  
            {   
                Thread.SpinWait(50000000); // do work here   
                BeginInvoke((Action)delegate { pb.Value++; });   
            });   
        });   
    }   
}  

Mise à jour des progrès bar à partir de l'intérieur d'un Parallel.For

Autres conseils

Ceci est l'un de mes résultats de recherche en haut et toujours pas d'exemple de progrès dans Task Parallel Library ici ...

Aujourd'hui, je viens de tomber sur TPL parce que je veux développer de nouvelles applications multithread mais sans utiliser BackgroundWorker (parce que je l'ai lu quelque part la tâche avec le code bien avant)

Je compiler l'exemple, réponse @Stephen Cleary, son lien assez compliqué pour de chercher des progrès, et quelques autres sites.

Ceci est l'exemple très simple comment faire Progrès et Terminé avec toute sécurité de thread d'interface utilisateur:

        TaskScheduler currentTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
        Task<string>.Factory.StartNew(() =>
        {
            // loop for about 10s with 10ms step
            for (int i = 0; i < 1000; i++)
            {
                Thread.Sleep(10);
                Task.Factory.StartNew(() =>
                {
                    // this is a task created each time you want to update to the UI thread.
                    this.Text = i.ToString();
                }, CancellationToken.None, TaskCreationOptions.None, currentTaskScheduler);
            }
            return "Finished!";
        })
        .ContinueWith(t =>
        {
            // this is a new task will be run after the main task complete!
            this.Text += " " + t.Result;
        }, currentTaskScheduler);

Le code affiche 1 à 1000 dans les 10 secondes, puis ajoutez un « Terminer! » chaîne dans les fenêtres forme barre de titre. Vous pouvez voir que le TaskScheduler est la façon délicate pour créer thread d'interface utilisateur mise à jour en sécurité parce que je pense que la tâche planifiée pour être exécutée sur thread principal.

Il n'y a pas de support intégré pour cela comme ce BackgroundWorker avait.

Vous pouvez utiliser SynchronizationContext directement; il y a une excellente vidéo ici:    http://www.rocksolidknowledge.com/ScreenCasts.mvc/Watch?video = TasksAndThreadAffinity.wmv

L'auteur développe deux solutions dans cette vidéo: une en utilisant SynchronizationContext et un autre à l'aide des tâches continuations. Pour votre problème, continuations ne fonctionnera pas, mais l'approche SynchronizationContext fonctionnerait très bien.

P.S. Si vous créez un code réutilisable, puis quand vous capturez SynchronizationContext.Current, vous devez tester pour nulle et (si elle est nulle), utilisez un SynchronizationContext par défaut construit à la place.

UPDATE : Je suis le code posté pour cette sur mon blog . Ma solution est en fait basée sur une Task qui est prévue au thread de l'interface utilisateur par un TaskScheduler qui utilise SynchronizationContext dessous. Contrairement à la réponse acceptée, cette solution fonctionne pour les deux formes WPF et Windows.

Le TPL est pas particulièrement orientée vers le soutien de l'interface utilisateur, vous pouvez (encore) utiliser un BackgroundWorker pour cela. En ce qui concerne l'envoi ou de la transformation des résultats intermédiaires, de nouveaux collectionclasses (ConcurrentQueue) à l'appui.

Pour signaler les progrès d'une tâche async, passer un Rapport avec les données de progression. L'appelant peut décider comment gérer ce rapport d'étape (à savoir l'ignorer, ou mettre à jour l'interface utilisateur).

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