masterofsea147: переводы
Concurrenc in C# Cookbook / Конкурентность в C# книга рецептов
→Reactive programming is based around the notion of observable streams. When you subscribe to an observable stream, you’ll receive any number of data items (OnNext) and then the stream may end with a single error (OnError) or “end of stream” notification (OnCompleted). Some observable streams never end. The actual interfaces look like this:<listing9>
0 Реактивное программирование основано на понятии наблюдаемых потоков. <Когда вы подписываетесь на наблюдаемый поток, вы получите любое количество элементов данных (OnNext), и тогда поток может завершиться с одной ошибкой (OnError) или уведомлением об окончании потока (OnCompleted). Некоторые из наблюдаемых потоков не прекращаются>. Вот как выглядит их интерфейс: <listing9>
→Reactive programming has a higher learning curve than other forms of concurrency, and the code can be harder to maintain unless you keep up with your reactive skills. If you’re willing to learn it, though, reactive programming is extremely powerful. Reactive programming allows you to treat a stream of events like a stream of data. As a rule of thumb, if you use any of the event arguments passed to an event, then your code would benefit from using Rx instead of a regular event handler.
0 Реактивное программирование является наиболее сложным в изучении типом конкурентности, его код сложнее поддерживать, если ваши навыки реактивного программирования еще не достаточно высоки. Если вы его изучите, оно станет вашим чрезвычайно мощным инструментом. Реактивное программирование позволяет вам обрабатывать поток событий как поток данных. Как правило, <если вы используете какой-либо из аргументов, передаваемых событию, тогда ваш код выиграет от использования Rx вместо обычного обработчика события.>
→1.4.Introduction to Reactive Programming (Rx)
0 1.4. Введение в реактивное программирование (Rx)
→Parallel Programming with Microsoft .NET, by Colin Campbell et al. (MSPress).
0 Parallel Programming with Microsoft .NET, by Colin Campbell et al. (MSPress).
→If you want to dive deeper into parallel programming, the best book on the subject is
0 Если вы хотите глубже изучить параллельное программирование, то я рекомендую вам прочитать лучшую книгу на эту тему -
→Tasks should not be extremely short, nor extremely long.
0 Задачи не должны быть ни слишком короткими, ни слишком длинными.
→Error handling is similar for all kinds of parallelism. Since operations are proceeding in parallel, it is possible for multiple exceptions to occur, so they are wrapped up in an AggregateException, which is thrown to your code. This behavior is consistent across Parallel.ForEach, Parallel.Invoke, Task.Wait, etc. The AggregateException type has some useful Flatten and Handle methods to simplify the error handling code:<listing9>
0 Обработка ошибок одинакова при всех видах параллелизма. Поскольку операции выполняются параллельно, возможно возникновение нескольких исключений одновременно. Они заключаются в экземпляр специального типа AggregateException. Это поведение одинаково для Parallel.ForEach, Parallel.Invoke, Task.Wait и т.д. Тип AggregateException имеет несколько полезных методов Flatten и Handle, предназначенных для упрощения процесса обработки ошибок: <listing9>
→Task parallelism should strive to be independent, just like data parallelism. The more independent your delegates can be, the more efficient your program can be. With task parallelism, be especially careful of variables captured in closures. Remember that clo‐ sures capture references (not values), so you can end up with sharing that isn’t obvious.
0 При параллелизме задач отдельно взятые части параллельного исполнения должны стремиться к абсолютной независимости друг от друга, как и при параллелизме данных. Чем более независимыми будут ваши делегаты, тем эффективнее может быть ваша программа. При параллелизме задач требуется соблюдать особенную осторожность с захваченными переменными в замыканиях. Не забывайте, что замыкания захватывают ссылки (а не значения), поэтому вы можете получить общий доступ, который не очевиден и может привести к проблемам потокобезопасности.
→The Task type was originally introduced for task parallelism, though these days it’s also used for asynchronous programming. A Task instance—as used in task parallelism— represents some work. You can use the Wait method to wait for a task to complete, and you can use the Result and Exception properties to retrieve the results of that work. Code using Task directly is more complex than code using Parallel, but it can be useful if you don’t know the structure of the parallelism until runtime. With this kind of dy‐ namic parallelism, you don’t know how many pieces of work you need to do at the beginning of the processing; you find it out as you go along. Generally, a dynamic piece of work should start whatever child tasks it needs and then wait for them to complete. The Task type has a special flag, TaskCreationOptions.AttachedToParent, which you could use for this. Dynamic parallelism is covered in Recipe 3.4.
0 Тип Task изначально был предназначен для параллелизма задач, однако теперь он также используется для асинхронного программирования. Экземпляр типа Task при использовании с параллелизмом задач - инкапсулирует в себе часть работы. Чтобы дождаться завершения задачи вы можете использовать метод Wait, в свою очередь, чтобы получить результаты выполнения этой задачи вы можете использовать свойства Result и Exception. Использование класса Task напрямую, сложнее, чем работа с типом Parallel, но он может быть полезен, если структура параллелизма не известна заранее (до начала времени исполнения). <При таком динамическом параллелизме вы не знаете, сколько частей вам нужно выполнить в начале обработки; Вы узнаете об этом по ходу дела>. Как правило, динамическая часть работы должна запускать любые дочерние задачи, в которых она нуждается, и затем ждать их завершения. Тип Task имеет для этого специальный флаг TaskCreationOptions.AttachedToParent. Динамический параллелизм описан в рецепте 3.4.
→The output of your parallel processing can be handled various ways. You can place the results in some kind of a concurrent collection, or you can aggregate the results into a summary. Aggregation is common in parallel processing; this kind of map/reduce functionality is also supported by the Parallel class method overloads. We’ll look at aggregation in more detail in Recipe 3.2.
0 <Результаты параллельной работы могут быть <обработаны> различными способами. Вы можете поместить их в какую-нибудь конкурентную коллекцию или объединить их в <сводку>. Агрегация - это основа параллельной обработки; этот вид map / reduce функциональности также поддерживается перегрузками метода класса Parallel. Рассмотрим агрегацию детальнее в рецепте 3.2.>
→As long as your chunk of work is independent from all other chunks, you maximize your parallelism. As soon as you start sharing state between multiple threads, you have to synchronize access to that shared state, and your application becomes less parallel. We’ll cover synchronization in more detail in Chapter 11.
0 До тех пор пока части выполняемой параллельно работы независимы друг от друга степень параллелизма максимальна. Однако как только вы предпринимаете попытки совместного использования состояния несколькими потоками, вы должны синхронизировать доступ к общему состоянию,что приводит к значительному снижению практической пользы параллелизма данных. Мы рассмотрим синхронизацию более подробно в 11 главе.
→One Parallel method that does a type of fork/join task parallelism is Parallel.In voke. This is covered in Recipe 3.3; you just pass in the delegates you want to execute in parallel:<listing8>
0 Один из методов класса Parralel реализует параллелизм задач типа разделение/соединение (fork/join) - это метод Parallel.Invoke. Пример его работы показан в рецепте 3.3; нужно всего лишь передать ему делегатов для их параллельного выполнения: <listing8>
→Now let’s turn to task parallelism. Data parallelism is focused on processing data; task parallelism is just about doing work.
0 Теперь давайте перейдем к параллелизму задач. Параллелизм данных ориентирован на обработку данных; параллелизм задач - это просто параллельное выполнение задач.
→The chunks of work should be as independent from each other as possible.
0 Параллельно обрабатываемые фрагменты должны быть максимально независимыми друг от друга.
→Regardless of the method you choose, one guideline stands out when doing parallel processing.
0 Независимо от выбранного вами метода, при параллельной обработке данных необходимо следовать единому правилу.
→Another option is PLINQ (Parallel LINQ), which provides an AsParallel extension method for LINQ queries. Parallel is more resource friendly than PLINQ; Parallel will play more nicely with other processes in the system, while PLINQ will (by default) attempt to spread itself over all CPUs. The downside to Parallel is that it is more explicit; PLINQ has more elegant code in many cases. PLINQ is covered in Recipe 3.5:<listing7>
0 Другой вариант - PLINQ (Parallel LINQ), который предоставляет метод расширения AsParallel для запросов LINQ. Parallel является более дружественным к ресурсам, чем PLINQ; Parallel будет учитывать взаимодействие с другими процессами в системе, в то время как PLINQ (по умолчанию) будет вести себя агрессивно, пытаясь занять собой все доступные процессоры. Однако, PLINQ имеет более элегантный код. Применение PLINQ показано в рецепте 3.5: <listing7>
→<table1>
0 <table1>
→There are a few different ways to do data parallelism. Parallel.ForEach is similar to a foreach loop and should be used when possible. Parallel.ForEach is covered in Recipe 3.1. The Parallel class also supports Parallel.For, which is similar to a for loop and can be used if the data processing depends on the index. Code using Paral lel.ForEach looks like this:<listing6>
0 Есть несколько способов реализации параллелизма данных. Метод Parallel.ForEach похож на цикл foreach и должен использоваться по возможности. Parallel.ForEach рассматривается в рецепте 3.1. Класс Parallel также предоставляет метод Parallel.For, который похож на цикл for и может использоваться, если обработка данных зависит от индексации. Код с использованием Parallel.ForEach выглядит следующим образом: <list6>
→There are two forms of parallelism: data parallelism and task parallelism. Data paral‐ lelism is when you have a bunch of data items to process, and the processing of each piece of data is mostly independent from the other pieces. Task parallelism is when you have a pool of work to do, and each piece of work is mostly independent from the other pieces. Task parallelism may be dynamic; if one piece of work results in several additional pieces of work, they can be added to the pool of work.
0 Существует две формы параллелизма: параллелизм данных и параллелизм задач. Параллелизм данных - это параллелизм, при котором у вас имеется множество фрагментов данных для обработки, и обработка каждого фрагмента производится независимо от остальных данных. Параллелизм задач - это параллелизм, при котором у вас есть пул работы, и каждая часть работы в основном независима от других частей. Параллелизм задач может быть динамическим - если одна часть работы приводит к нескольким дополнительным частям, они могут быть добавлены в пул работы.
→Parallel programming should be used any time you have a fair amount of computation work that can be split up into independent chunks of work. Parallel programming in‐ creases the CPU usage temporarily to improve throughput; this is desirable on client systems where CPUs are often idle but is usually not appropriate for server systems. Most servers have some parallelism built in; for example, ASP.NET will handle multiple requests in parallel. Writing parallel code on the server may still be useful in some situations (if you know that the number of concurrent users will always be low), but in general, parallel programming on the server would work against the built-in parallelism and would not provide any real benefit.
0 Параллельное программирование должно использоваться всякий раз, когда у вас есть значительное количество вычислительной работы, которая может быть разделена на независимые части. Параллельное программирование временно увеличивает нагрузку на процессор для повышения пропускной способности; это отлично подходит для клиентских систем, где процессоры часто простаивают, но редко подходят для серверов. Большинство серверных систем имеют встроенный параллелизм; например, ASP.NET обрабатывает несколько запросов параллельно. Написание параллельного кода для серверного приложения, однако,может быть полезно в некоторых ситуациях (если вы заранее знаете, что число пользователей одновременно работающих с сервером будет небольшим), но в большинстве других случаев параллелизм для сервера не принесет какой-либо практической выгоды.
Резюме
- Пол:
- мужчина
- Родной язык:
- русский
- С нами:
- с 7 марта 2019 г. (2780 дней) по приглашению Artona
- Деятельность:
-
289 версий перевода
с общим рейтингом 38
20 комментариев
