Поддержка отчетов о ходе выполнения и дополнительных результатов в .NET 4.0 «Библиотека параллельных задач»

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

Вопрос

я знаю это Параллельная библиотека задач все еще находится в бета-версии, и ресурсов, вероятно, будет меньше, но, судя по тому, что я читал, библиотека уделяет особое внимание планирование задач, Обработка исключений и отмена.

Но я не нашел упоминаний о отчет о ходе работы и отправка дополнительных результатов из задач.Эти две вещи кажутся слишком важными, чтобы их игнорировать.Можете ли вы пролить свет на то, как с ними обращаться в библиотеке параллельных задач, или сослаться на некоторые статьи, в которых они объясняются?

Это было полезно?

Решение

В этом примере обновляется индикатор выполнения:

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

Обновление индикатора выполнения изнутри Parallel.For

Другие советы

Это один из моих лучших результатов поиска, но он до сих пор не является примером прогресса в Task Parallel Library Прямо здесь...

Сегодня я только что наткнулся на TPL, потому что хочу разработать новое многопоточное приложение, но без использования BackgroundWorker (потому что я раньше где-то читал о задаче с красивым кодом)

Я компилирую пример из ответа @Stephen Cleary, его ссылка довольно сложна для поиска прогресса, а также некоторых других веб-сайтов.

Это очень простой пример того, как это сделать Прогресс и Завершенный с безопасным потоком пользовательского интерфейса:

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

Код отобразит от 1 до 1000 в пределах 10 с, а затем добавит «Отдел!» Строка в строке заголовка формы Windows.Вы можете видеть, что TaskScheduler — это сложный способ создать потокобезопасное обновление пользовательского интерфейса, поскольку я думаю, что задача, запланированная для запуска в основном потоке.

Для этого нет встроенной поддержки, подобной той, что была в BackgroundWorker.

Вы можете использовать SynchronizationContext напрямую;здесь есть отличное видео: http://www.rocksolidknowledge.com/ScreenCasts.mvc/Watch?video=TasksAndThreadAffinity.wmv

В этом видео автор развивает два решения:один использует SynchronizationContext, а другой - продолжение задачи.Для вашей проблемы продолжения не подойдут, но подход SynchronizationContext подойдет.

P.S.Если вы создаете повторно используемый код, то при захвате SynchronizationContext.Current вам следует проверить значение null и (если оно равно null) вместо этого использовать SynchronizationContext, созданный по умолчанию.

ОБНОВЛЯТЬ:Я разместил код для этого в моем блоге.Мое решение на самом деле основано на Task который запланирован обратно в поток пользовательского интерфейса с помощью TaskScheduler который использует SynchronizationContext под.В отличие от принятого ответа, это решение будет работать как для WPF, так и для Windows Forms.

TPL не особенно ориентирован на поддержку пользовательского интерфейса, вы (все еще) можете использовать для этого BackgroundWorker.Что касается отправки или обработки промежуточных результатов, для поддержки этого существуют новые классы коллекций (ConcurrentQueue).

Чтобы сообщить о ходе выполнения асинхронной задачи, передайте IPProgress в асинхронный метод.Внутри метода вызовите Отчет с данными о ходе работы.Вызывающий может решить, как обрабатывать этот отчет о ходе работы (т. е.Игнорируйте это или обновите пользовательский интерфейс).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top