Apoyo de los informes de progreso y resultados incrementales en .NET 4.0 “tarea paralela Biblioteca”

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

Pregunta

Sé que tarea paralela Biblioteca todavía está en beta y no es probable que sean menos recursos disponibles, sino de todo lo que he leído, biblioteca da un tratamiento muy especial a programación de tareas , control de excepciones y cancelación .

Pero no encuentro ninguna referencia a el progreso de informes Resultados incrementales y el envío de tareas. Estas 2 cosas parecen demasiado importante como para ignorarlo. Se puede arrojar alguna luz sobre cómo manejar estos en paralelo Biblioteca de tareas o consultar algunos artículos que les explica?

¿Fue útil?

Solución

En este ejemplo se actualiza una barra de progreso:

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

Actualización de un progreso bar por dentro de un Parallel.For

Otros consejos

Esta es una de mis principales resultados de la búsqueda y todavía ningún ejemplo para el progreso en Task Parallel Library aquí ...

Hoy me encontré con TPL porque quiero desarrollar una nueva aplicación multiproceso pero sin utilizar BackgroundWorker (porque he leído en alguna parte acerca de tareas con el código de buena antes)

puedo compilar el ejemplo de la respuesta @Stephen Cleary, su vínculo bastante complicado para buscar el progreso, y algunos otros sitios web.

Este es el ejemplo muy simple de cómo hacer Progreso y Finalizado con forma segura hilo de interfaz de usuario:

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

El código se mostrará 1 a 1000 dentro de 10 segundos y luego añadir una "Finalizar" cadena en las ventanas forman la barra de título. Se puede ver que la TaskScheduler es el camino complicado para crear hilo de interfaz de usuario de actualización segura porque creo que la tarea programada para ejecutarse en el hilo principal.

No existe soporte integrado para este BackgroundWorker como lo que había hecho.

Puede utilizar SynchronizationContext directamente; hay un excelente video aquí:    http://www.rocksolidknowledge.com/ScreenCasts.mvc/Watch?video = TasksAndThreadAffinity.wmv

El autor desarrolla dos soluciones en este video: uno utilizando SynchronizationContext y otro usando continuaciones de tareas. Para su problema, continuaciones no funcionarán, pero el enfoque SynchronizationContext funcionarían bien.

P.S. Si va a crear código reutilizable, a continuación, cuando se captura SynchronizationContext.Current, debe probar para nulo y (si es nulo) utilizar un SynchronizationContext default-construida en su lugar.

Actualizar : He publicado código para esta en mi blog . Mi solución se basa realmente en una Task que está programado de nuevo al hilo de interfaz de usuario por un TaskScheduler que utiliza SynchronizationContext debajo. A diferencia de la respuesta aceptada, esta solución va a funcionar para ambas formas de WPF y Windows.

El TPL no está orientada sobre todo hacia el soporte de interfaz de usuario, puede (aún) utilizar un BackgroundWorker para eso. Como para el envío o el procesamiento de los resultados intermedios, hay nuevas collectionclasses (ConcurrentQueue) para apoyar eso.

Para informar sobre el progreso de una tarea asíncrona, aprobar un IProgress en el método asíncrono. Dentro del método, llamado Informe con los datos de progreso. La persona que llama puede decidir cómo manejar ese informe de situación (es decir, lo ignoran, o actualizar la interfaz de usuario).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top