вторник, 23 августа 2011 г.

Parallel Programming - ожидания завершения задач

Задача: нужно дождаться окончания выполнения одной или нескольких задач.

Решение: используйте методы Wait, WaitAll или WaitAny класса System.Threading.Task.

Как это работает

Метод Wait вызванный у экземпляра класса Task блокирует вызывающий поток до тех пор, пока задача не завершится. Статические методы WaitAll и WaitAny принимают в качестве аргументов массив задач. Метод WaitAll блокирует вызывающий поток до тех пор, пока ВСЕ задачи из переданного массива задач не закончат выполняться. Метод WaitAny блокирует вызывающий поток до тех пор пока хотя бы одна из задач не выполнится.
Эти методы также принимают в качестве аргумента количество миллисекунд - время ожидания выполнения задачи. Если за это время задача не успела выполниться, ожидание прекращается и продолжается выполнения кода.
Свойство IsCompleted класса Task используется для определения завершения задачи.

Пример кода.
Используемые пространства имен:
using System.Threading;
using System.Threading.Tasks;

Тестовый класс:

    public class WaitTest
    {
        private int WriteDays()
        {
            string[] daysArray = {
                "Понедельник",
                "Вторник",
                "Среда",
                "Четверг",
                "Пятница",
                "Суббота",
                "Воскресенье"
            };

            foreach (string day in daysArray)
            {
                Console.WriteLine("День недели: {0}", day);
                // подвешиваем текущий поток и даем возможность отработать другим потокам
                Thread.Sleep(500);
            }

            return daysArray.Length;
        }

        private int WriteMonths()
        {
            string[] monthsArray =
            {
                "Янв", "Фев", "Мар", "Апр",
                "Май", "Июн", "Июл", "Авг",
                "Сен", "Окт", "Ноя", "Дек"
            };

            foreach (string month in monthsArray)
            {
                Console.WriteLine("Месяц: {0}", month);
                // подвешиваем текущий поток и даем возможность отработать другим потокам
                Thread.Sleep(500);
            }

            return monthsArray.Length;
        }

        private int WriteCities()
        {
            string[] citiesArray = { "Москва", "Лондон", "Шанхай", "Стокгольм", "Таллинн" };

            foreach (string city in citiesArray)
            {
                Console.WriteLine("Город: {0}", city);
                // подвешиваем текущий поток и даем возможность отработать другим потокам
                Thread.Sleep(500);
            }

            return citiesArray.Length;
        }

        public void StartTest()
        {
            // при каждом вызове StartNew запускается новая задача
            Task<int> task1 = Task<int>.Factory.StartNew(WriteDays);
            Task<int> task2 = Task<int>.Factory.StartNew(WriteMonths);
            Task<int> task3 = Task<int>.Factory.StartNew(WriteCities);

            // Так можно дождаться завершения выполнения конкретной задачи:
            //task1.Wait();

            // дожидаемся завершения всех задач:
            Task.WaitAll(task1, task2, task3);

            // Получаем результат от задач
            // При каждом вызове свойства Result, текущий поток подвисает
            // до получения результата из задачи
            Console.WriteLine("{0} дней", task1.Result);
            Console.WriteLine("{0} месяцев", task2.Result);
            Console.WriteLine("{0} городов", task3.Result);
        }
    }




Источник: "C# 2010 Recipes - A Problem Solution Approach" Allen Jones and Adam Freeman.

Предыдущая статья: "Parallel Programming - получение результата выполнения задачи"

Комментариев нет:

Отправить комментарий