Net framework 5, а также среды Visual Studio 2012 и C#



Download 6,27 Mb.
Pdf ko'rish
bet577/658
Sana12.06.2023
Hajmi6,27 Mb.
#950840
1   ...   573   574   575   576   577   578   579   580   ...   658
Bog'liq
CLR via C Programmirovanie na platforme Microsoft NET Framework 4 5 na yazyke C


Глава.27 .Асинхронные.вычислительные.операции
Если у вас есть выбор между 
For
и 
ForEach
, лучше используйте цикл 
For
, так 
как он работает быстрее.
Если вам нужно выполнить несколько методов, можно сделать это последова-
тельно — например, вот так:
// Один поток выполняет методы по очереди
Method1();
Method2();
Method3();
Также возможно параллельное выполнение:
// Потоки из пула выполняют методы одновременно
Parallel.Invoke(
() => Method1(),
() => Method2(),
() => Method3());
Все методы класса 
Parallel
заставляют вызывающий поток принимать участие 
в их обработке. Это хорошо с точки зрения расходования ресурсов, так как вызыва-
ющий поток не блокируется, ожидая выполнения работы потоками пула. Впрочем, 
если выполнение вызывающего потока будет закончено до того, как потоки из пула 
выполнят свою часть, вызывающий поток приостанавливается до их завершения, 
что тоже неплохо, так как обеспечивает семантику, аналогичную применению 
цикла 
for
или 
foreach
. Выполнение вызывающего потока не возобновляется, пока 
не будет завершена вся работа. Если какая-либо операция станет источником не-
обработанного исключения, вызванный вами метод 
Parallel
выдаст исключение 
AggregateException
.
Разумеется, это не значит, что все циклы 
for
в своем коде следует заменить вы-
зовами 
Parallel.For
, а циклы 
foreach
— вызовами 
Parallel.ForEach
. Вызовы 
Parallel
базируются на предположении, что рабочие элементы без проблем смогут 
выполняться параллельно. Значит, для заданий, которые должны выполняться 
последовательно, вызов этого метода не имеет смысла. Следует также избегать ра-
бочих элементов, вносящих изменения в любые совместно используемые данные, 
так как при одновременном управлении несколькими потоками эти данные могут 
оказаться поврежденными. Обычно эта проблема решается в рамках синхронизации 
потоков блокированием фрагментов кода, в которых реализуется доступ к данным. 
Однако так как после этого доступ к данным в каждый момент времени сможет по-
лучать только один поток, теряется преимущество одновременного обслуживания 
множества элементов.
Кроме того, методы класса 
Parallel
потребляют много ресурсов — приходится 
выделять память под делегаты, которые вызываются по одному для каждого рабочего 
элемента. При наличии множества рабочих элементов, которые могут обслуживать-
ся разными потоками, можно получить рост производительности. К тому же если 
каждый элемент выполняет много работы, на снижение производительности из-за 
вызова делегатов можно не обращать внимания. Проблемы начинаются в случае, 


773
Методы.For,.ForEach.и.Invoke.класса.Parallel
когда методы класса 
Parallel
применяются к небольшому числу рабочих элементов 
или же к элементам, обслуживание которых происходит очень быстро.
Следует упомянуть, что для методов 
For

ForEach
и 
Invoke
класса 
Parallel
существуют перегруженные версии, принимающие объект 
ParallelOptions
. Вот 
как он выглядит:
public class ParallelOptions{
public ParallelOptions();
// Допускает отмену операций
public CancellationTokenCancellationToken { get; set; } 
// По умолчанию CancellationToken.None
// Позволяет задать максимальное количество рабочих
// элементов, выполняемых одновременно
public Int32MaxDegreeOfParallelism { get; set; } 
// По умолчанию -1 (число доступных процессоров)
// Позволяет выбрать планировщика заданий
public TaskSchedulerTaskScheduler { get; set; } 
// По умолчанию TaskScheduler.Default
}
Существуют перегруженные версии и для методов 
For
и 
ForEach
, позволяющие 
передавать три делегата:
‰
Делегат локальной инициализации задания (
localInit
) для каждой выпол-
няемой задачи вызывается только один раз — перед получением команды на 
обслуживание рабочего элемента.
‰
Делегат 
body
вызывается один раз для каждого элемента, обслуживаемого уча-
ствующими в процессе потоками.
‰
Делегат локального состояния каждого потока (
localFinally
) вызывается 
один раз для каждого задания, после того как оно обслужит все переданные ему 
рабочие элементы. Также он вызывается, если код делегата 
body
становится ис-
точником необработанного исключения.
Следующий пример кода демонстрирует использование этих трех делегатов на 
примере суммирования байтов для всех файлов, содержащихся в каталоге:
private static Int64 DirectoryBytes(String path, String searchPattern,
SearchOptionsearchOption) {
var files = Directory.EnumerateFiles(path, searchPattern, searchOption);
Int64 masterTotal = 0;
ParallelLoopResult result = Parallel.ForEach(
files,
() => { // localInit: вызывается в момент запуска задания
продолжение



774
Download 6,27 Mb.

Do'stlaringiz bilan baham:
1   ...   573   574   575   576   577   578   579   580   ...   658




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish