понедельник, 22 августа 2011 г.

Parallel Programming - вступление

С новой версией .NET Framework 4.0 корпорация Microsoft представила новую модель для написания многопоточных приложений - эта модель известна как параллельное программирование (parallel programming) и ее реализация называется Task Parallel Library. В отличие от традиционного подхода в многопоточности, где вы создаете и управляете набором потоков в вашем коде, новая модель позволяет вам сфокусироваться в первую очередь на задачах, которые вам нужно выполнить. Среда выполнения выполнит всю "грязную" работу за вас.
Основной недостаток этого подхода в том, что ваш код нацелен на задачи, которые нужно выполнять, а не на то КАК они должны выполняться. Другими словами, вы теряете полный контроль над многопоточным выполнением кода. В принципе, для большинства приложений это не критично. Но если вам нужна тонкая настройка и контроль над потоками, пользуйтесь классической многопоточной моделью.

Простейший пример выполнения нескольких задач параллельно.


Задача: нужно выполнить несколько задач (методов) параллельно.

Решение: нужно воспользоваться методом Invoke класса System.Threading.Parallel, передав в него экземпляр делегата System.Action для каждого метода, который вы хотите выполнить.

Пример кода.
Подключаем к классу следующие пространства имен:
using System.Threading;
using System.Threading.Tasks;

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

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

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

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

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

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

        public void StartTest()
        {
            // 1-ый вариант вызова:
            Parallel.Invoke(
                new Action(WriteDays),
                new Action(WriteMonths),
                new Action(WriteCities)
                );

            // 2-ой вариант вызова:
            Parallel.Invoke(
                () => WriteDays(),
                () => WriteMonths(),
                () => WriteCities()
                );

            // 3-ий вариант вызова:
            Parallel.Invoke(
                WriteDays,
                WriteMonths,
                WriteCities
                );
        }
    }

Результат выполнения:

День недели: Понедельник
Месяц: Янв
День недели: Вторник
Месяц: Фев
Город: Москва
День недели: Среда
Месяц: Мар
Город: Лондон
День недели: Четверг
Месяц: Апр
Город: Шанхай
День недели: Пятница
Месяц: Май
Город: Стокгольм
День недели: Суббота
Месяц: Июн
Город: Таллинн
День недели: Воскресенье
Месяц: Июл
Месяц: Авг
Месяц: Сен
Месяц: Окт
Месяц: Ноя
Месяц: Дек



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

Дополнительная полезная информация: "Работа с потоками в C#"

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

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