Г. Шилдт - С#4.0 Полное руководство (1160795), страница 184
Текст из файла (страница 184)
Прерывание цикла, параллельно выполняемого методом Рог (), нередко оказывается полезным при поиске данных. Так, если искомое значение найдено, то продолжать выполнение цикла нет никакой надобности. Прерывание цикла может оказатьо( полезным и в том случае, если во время очередной операции встретились недостоверные данные. В приведенном ниже примере программы демонстрируется применение метода Вгеак () длл прерывания цикла, параллельно выполняемого методом Рог () . Это вариант предыдущего примера, переработанный таким образом, чтобы метод Мутгапв готт () принимал теперь объект типа Рага11е1Ьоорэгаге в качестве своего параметра, а метод Вгеак () вызывался при обнаружении отрицательного значения в массиве данных.
Отрицательное значение, по которому прерывается выполнение цикла, вводится в массив бага внутри метода Магп () . Далее проверлется состояние завершения цикла преобразования данных. Свойство 1веовр1егеб будет содержать логическое значение га1 з е, поскольку в массиве бага обнаруживается отрицательное значение. При этом на экран выводится номер шага, на котором цикл был прерван.
(В этой программе исключены все избыточные циклы, применявшиеся в ее предыдущей версии, а оставлены только самые эффективные из них: последовательно выполняемый цикл инициализации и параллельно выполняемый цикл преобразования.) // Использовать объекты типа Рага11е1Ьооркевц1Г и Рага11е1Ьоорзсасе, а также Д/ метод ВгеаК() вместе с методом Рог() для параллельного выполнения цикла. пагод Яувгею; цвьпс Яувсею.тнгеабтпд.тавКв; с1авв пеюорага11е1Рогыгспьоорневц1Г ( вгаггс Ьпг[] бага; О Метод, служащий в качестве тела параллельно выполняемого цикла.
Операторы этого цикла просто расходуют время ЦП для целей демонстрации. всасьс чогб Мутгапвтогю(1пс г, Рага11е1Ьоорзсасе р1в) ( // Прервать цикл при обнаружении отрицательного значения. 11(баса[1] < О) р1в.ВгеаК(); баса(г] = баса(г] / 10; гт(баса(г] < 1000) баса[1] = 0; гг(бага(г] ) 1000 а бага[а] < 2000) бага(1] = 100; 1г Ьзага(1] > 2000 а бага[1) < 3000) баса(г] = 200," га(бага(1] > 3000) бага(1] = 300; ) всасьс чогб Маго() ( Глава 24. Многопоточное программирование. Часть вторая: библиотека ТР~ 915 Сопво1е.нггпеьзпе("Основной поток запущен."); бага = пен топ[100000000]Г Гу Инициализировать данные. Рог (Ьпс ь=бг 1 < бага. Ьепдпш т++) бапа[т] = 1г Поместить отрицательное значение в массив бага. сапа[1000] = -10Г Параллельный вариант инициализации массива в цикле. Рага11е1Ьоорвезп1С 1оорКезц1с = Рага11е1.Рог(0, баса.ьепппл, Мутгапзтошп) /У Проверить, завершился ли цикл.
гГ(!1оорпезц1С.1всошр1епеб) Сопзо1е.иггсеьт ее ("1пцикп завершился преждевременно из-за того, "что обнаружено отрицательное значение1п" + "на шаге цикла номер 1ооркеац1с.ьоне*свгеак1сегас1оп + ".1п")г Сопао1е.нггпеььпе("Основной поток завершен.") Выполнение этой программы может привести, например, к следующему результату. Основной поток запущен. Цикл завершился преждевременно из-за того, что обнаружено отрицательное значение на шаге цикла номер 1000 Основной поток завершен. Как следует из приведенного выше результата, цикл преобразования данных преждевременно завершается после 1000 шагов.
Дело в том, что метод вгеаи () вызывается внутри метода Мутгапз Роги () при обнаружении в массиве данных отрицательного значения. Помимо двух описанных выше форм метода Рог ( ) существует и ряд других его форм. В одних из этих форм допускается указывать различные дополнительные параметры, а в других — использовать параметры типа 1опо вместо 1пг для пошагового выполнения цикла. Имеются также формы метода Рог (), предоставляющие такие дополнительные преимущества, как, например, возможность указывать метод, вызываемый по завершении потока каждого цикла. И еще одно, последнее замечание: если требуется остановить цикл, параллельно выполняемый методом Рог ( ), не обращая особого внимания на любые шаги цикла, которые еще могут быть в нем выполнены, то для этой цели лучше воспользоваться методом Бсср (), чем методом Вгеа)г () .
ПРИМОНОНИО МОТОАЗ ГОХЕОС)1 () Используя метод Рогвас)т (), можно создать распараллеливаемый вариант цикла Гогеас)ь Существует несколько форм метода Рогвас)г () . Ниже приведена простейшая форма его объявления; 916 Часть! 1. Библиотека С№ риЫ1с ятаттс Рага11е1Ьооряеяи1т Рогкасп<ТЯоигсе>(1ЕпивегаЬ1е<ТЯоигсе> яоигсе, Асттоп<тзоигсе> Вооу) где яоитсе обозначает коллекцию данных, обрабатываемых в цикле, а Ьос(у — метод, который будет выполняться на каждом шаге цикла. Как полопалось ранее в этой книге, во всех массивах, коллекциях (описываемых в главе 25) и других источниках данных поддерживается интерфейс 1ЕпиветаЬ1е<Т>. Метод, передаваемый через параметр Ьос(у, принимает в качестве своего аргумента значение или ссылку на каждый обрабатываемый в цикле элемент массива, но не его индекс.
А в итоге возвращаются сведения о состоянии цикла. Аналогично методу Рот [), параллельное выполнение цикла методом РотЕасЛ () можно остановит(а вызвав метод Вгеак () для экземпляра объекта типа Ра га11е1ьооря гасе, передаваемого через параметр Ьо<(у, при условии, что используется приведенная ниже форма метода РогЕасп () .
риЬ)ьс ятаттс Рага11е1Ьоорвеяи1т РогкасЬ<ТЯоигсе>(1ЕпивегаЬ1е<тзоигсе> яоигсе, Асгтоп<тяоитсе, Рата11е1ьоорятате> Ьо<(у) В приведенном ниже примере программы демонстрируется применение метода РотЕасп () на практике. Как и прежде, в данном примере создается крупный массив целых значений. А отличается данный пример от предыдущих тем, что метод выполняющийся на каждом шаге цикла, просто выводит на консоль значения из массива. Как правило, метод Хг1геЬ1пе () в распараллеливаемом цикле не применяетсл, потому что ввод-вывод на консоль осуществляется настолько медленно, что цикл оказывается полностью привязанным к вводу-выводу. Но в данном примере метод Ит1геЬтпе () применяется исключительно в целях демонстрации возможностей метода РотЕасп () .
При обнаружении отрицательного значения выполнение цикла прерывается вызовом метода Втеа)< () . Несмотря на то что метод Втеак () вызывается в одной задаче, другая задача может по-прежнему выполняться в течение нескольких шагов цикла, прежде чем он будет прерван, хотя это зависит от конкретных условий работы среды выполнения. // Использовать обьекты типа Рага11е1Ьооркеяи1т и Рага11е1ЬоорБтате, а также // метод Вгеак() вместе с методом РогкасЬ() для параллельного выполнения цикла. иягпо Яуятев; ия1по Буятев.тдгеабгпд.Таякя; с1аяя Оеворага11е1Рогигтььооркеяи1Г ягат1с тпт() бата; // Метод, служавий в качестве тела параллельно выполняемого цикла. В данном примере переменной ч передается значение элемента массива данных, а не индекс этого элемента.
ятаттс чотб Втяр1ауоата(тпт ч, Рага11е1ЬоорЯГаге р1я) ( О Прервать цикл при обнаружении отрицательного значения. 1Т(ч < О) р1я.эгеак()г Сопяо1е.игттеььпе("Значение: " + ч) ) Глава 24. Многопоточное программирование. Часть вторая: библиотека ТРП 917 згагго чогб Магд() ( Солво1е.иггсеььпе("Основной поток запущен.") баса = пем глс[100000000); О Инициализировать данные. гог(глг г=с) г < бага.ьелчггп 1++) бага[г) Поместить отрицательное значение в массив бага. баса[100000) = -10; // Использовать цикл, параллельно выполняемый методом Гогйаоб(), // для отображения данных на экране.
Рага11е1Ьоорревц1Г 1оорйевц1Г = Рага11е1.Гогйасн(баса, Пгвр1ауПаса) УУ Проверить, эавершилоя ли цикл. гс(!1оорйевч1с.твСотр1есеб) Солво1е.нг1сеььле("1лцикл завершился преждевременно из-за того, "что обнаружено отрицательное значение1о" "на шаге цикла номер " + 1оорйезц1с.ьоневсэгеа)г1гегаггоп + ". 1л")) Солво1е.нггсеЬгпе("Основной поток завершен.") ) В приведенной выше программе именованный метод применяется в качестве делегата, представляющего "тело" цикла.
Но иногда удобнее применять анонимный метод. В качестве примера ниже приведено реализуемое в виде лямбда-выражения "тело" цикла, параллельно выполняемого методом Гогйас)т () . О Использовать цикл, параллельно выполняемый методом Гогйасн() О для отображения данных на экране. Рага11е1Ьоорйезц11 1оорйезц1Г = Рага11е1 . Гогйась (баса, (ч, р1в) < > ( Солво1е.иггсеЬгле("Значение: " + ч); 1Г(ч < О) р1в.эгеак(); )): Исследование возможностей РЫЧЯ Р[.1)Х[ ) представляет собой параллельный вариант языка интегрированных запросов 1.1[х[О и тесно связан с библиотекой ТР[..
Р1.1ЫЯ применяется, главным образом, для достижения параллелизма данных внутри запроса. Как станет ясно из дальнейшего, сделать это совсем не трудно. Как и ТР1., тема Р1.1[Щ довольно обширна и многогранна, поэтому в этой главе представлены лишь самые основные понятия данного языка. КлаСС Рага11е1Егг)лпегаЬ1е Основу Р[.1ХО составляет класс Ра га11е1Епцшега)з1е, определенный в пространстве имен Я уз сеш.
ЬЬП<(. Это статический класс, в котором определены многие 918 Часть )). Библиотека С(г методы расширения, поддерживающие параллельное выполнение операций. По существу, он представляет собой параллельный вариант стандартного для Ы)Щ класса ЕпивегаЬ1е. Многие его методы являются расширением класса Рага11е1Оиегу, а некоторые из них возвращают объект типа Рага11е1Оиегу. В классе Рага11е1(]негу инкапсулируется последовательность операций, поддерживающая параллельное выполнение.