Unterstützung des Fortschritts Berichterstattung und inkrementelle Ergebnisse in .NET 4.0 „Task Parallel Library“

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

Frage

Ich weiß, dass Taskbibliothek Parallel noch in der Beta und es gibt wahrscheinlich weniger Ressourcen zur Verfügung stehen, aber von was auch immer mir gelesen habe, Bibliothek gibt sehr spezielle Behandlung auf Task-Scheduling , Ausnahmebehandlung und Stornierung .

Aber ich finde keine Hinweise auf Fortschritt Berichterstattung und Senden inkrementelle Ergebnisse von Aufgaben. Diese zwei Dinge scheinen zu wichtig, zu ignorieren. Können Sie etwas Licht auf werfen, wie diese in Aufgabe behandeln Parallel Library oder einige Artikel beziehen, die sie erklärt?

War es hilfreich?

Lösung

In diesem Beispiel aktualisiert eine Fortschrittsbalken:

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++; });   
            });   
        });   
    }   
}  

einen Fortschritt aktualisiert Bar aus dem Inneren eines Parallel.For

Andere Tipps

Dies ist einer meines Top-Sucher und noch kein Beispiel für den Fortschritt in Task Parallel Library hier ...

Heute habe ich kam gerade über TPL, weil ich neue Multithread-Anwendung entwickeln möge, aber ohne BackgroundWorker zu verwenden (weil ich irgendwo über Aufgabe mit schönem Code vorher gelesen)

ich das Beispiel von @Stephen Cleary Antwort kompilieren, seine Verbindung ganz zu achten ist für den Fortschritt kompliziert, und einige andere Websites.

Dies ist sehr einfaches Beispiel, wie zu tun Fortschritt und Fertig mit UI sicherer Art und Weise einfädeln:

        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);

Der Code wird 1 bis 1000 innerhalb von 10 Sekunden angezeigt und dann einen anhang „Fertig!“ String in den Fenstern bilden Titelleiste. Sie können sehen, dass die Taskscheduler der schwierige Weg UI-Thread sicher Updates zu erstellen, weil ich die Aufgabe denke geplant auf Haupt-Thread ausgeführt werden.

Es gibt keine eingebaute Unterstützung für diese wie das, was Background hatte.

Sie können SynchronizationContext direkt verwenden; Es gibt eine ausgezeichnete Video hier:    http://www.rocksolidknowledge.com/ScreenCasts.mvc/Watch?video = TasksAndThreadAffinity.wmv

Der Autor entwickelt zwei Lösungen in diesem Video: ein SynchronizationContext und eine andere mit dem Task-Fortsetzungs verwenden. Für Ihr Problem, Fortsetzungen werden nicht funktionieren, aber der SynchronizationContext Ansatz würde gut funktionieren.

P. S. Wenn Sie wieder verwendbaren Code erstellen, dann, wenn Sie erfassen SynchronizationContext.Current, sollten Sie für null testen und (wenn es null ist) verwenden, um eine Standard ausgebaute SynchronizationContext statt.

UPDATE : Ich habe für diese geschrieben Code auf meinem Blog . Meine Lösung ist auf einem Task tatsächlich basiert, die aus dem UI-Thread von einem TaskScheduler geplant ist, die SynchronizationContext darunter verwendet. Anders als die akzeptierte Antwort, funktioniert diese Lösung für beide WPF und Windows Forms.

Die TPL ist nicht besonders orientiert UI-Unterstützung können Sie (noch) einen Background dafür. Wie für das Senden oder die Verarbeitung von Zwischenergebnissen gibt es neue collectionclasses (ConcurrentQueue), das zu unterstützen.

Um Bericht Fortschritte von einer Asynchron-Aufgabe, übergeben Sie ein Bericht mit die Fortschrittsdaten. Der Anrufer kann entscheiden, wie, dass die Fortschritte Bericht zu behandeln (d Ignorieren Sie es, oder die Benutzeroberfläche aktualisieren).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top