.NET

От Энтерры – казахстанским автовладельцам. Удобная система поиска автозапчастей.

Мы недавно помогли заказчикам из Казахстана очень сильно обрадовать автовладельцев. Там не оказалось удобного сервиса, который особенно необходим, когда срочно нужны запчасти, но по магазинам ездить – не слишком удобно, а иногда уже и не на чем. Его, честно говоря, и у нас в стране тоже пока нет. Вот мы его и сделали, а называется он Auto-Market. Можно бы на том и закончить, но, по старой традиции, мы решили добавить подробностей – специально для любителей погружаться в детали.

 

auto-market1

Сервис может показаться удивительно простым. Auto-Market всего лишь собирает по заявке автовладельца предложения от зарегистрированных в системе автомагазинов по конкретной детали для его автомобиля, а пользователь потом может выбрать лучшее. Также можно найти подходящий по автомобилю, времени работы или расположению сервисный центр. И это все. Но за его внешней простотой скрывается пара любопытных вещей.

auto-market2

Сначала об автовладельцах. Для пользователей все просто – они регистрируются на сайте Auto-Market.kz или через одно из приложений (для iOS или Android) с таким же функционалом. После этого сразу можно не откладывая приступать к поиску детали. После регистрации сервис продолжает быть воплощением простоты и таланта краткости. Весь интерфейс составляют всего четыре кнопки: «управление личным кабинетом», «история запросов», «поиск запчасти» и «поиск магазина или сервиса».

auto-market4

Сохранить можно любое количество машин. По сути это все – дальше можно только набирать в поиске запчасти, которые нужны. Система сама отследит, каких поставщиков оповестить, исходя из того, какими запчастями или услугами они занимаются, и разошлет им запросы. Пользователю остается только дождаться ответов поставщиков и выбрать лучшее предложение.

auto-market5

Как легко заметить – первые ответы начинают приходить уже через пару минут. Правда, в данном случае они не радуют – этой запчасти нет, но согласитесь, узнать об этом таким способом гораздо выгоднее и даже приятнее, чем приехав на место или потратив свое личное время на обзвон десятков магазинов.

С автовладельцами, кажется, все понятно. Теперь о другой стороне медали. Сервисные пункты и магазины автозапчастей с помощью системы сокращают зависимость от своего места расположения или известности. Теперь выбор клиента определяют быстрый ответ магазина и хорошее предложение. Также возможен вариант, при котором покупатель выберет комфорт и удобство, несмотря на чуть более высокую цену. Если магазин расположен недалеко от его места жительства или работы, например. В общем, даже если магазин не слишком известен и находится в не очень удобном месте – он все равно может найти своего клиента. Ну и отвечать на запросы стало гораздо проще.

auto-market6

Правда, чтобы зарегистрироваться в системе автомагазин или сервисный центр должен потратить чуть больше времени – минут пятнадцать. Вначале надо скачать с сайта приложение для участников и запустить его.

auto-market7

Приложение поспрашивает немного – что за магазин, какими запчастями торгует и реквизиты, чтобы можно было выставить счет. И отправит данные на одобрение модератору. Если все корректно – в системе появится новый участник.

auto-market8

В итоге вся система работает как сложная база данных, объединяющая покупателей и продавцов. В системе администратор управляет основным ресурсом, который по параметрам автоматически распределяет заказы клиентов между магазинами. С одной стороны параметры поиска указывает покупатель, а с другой – задают магазины, чтобы отсекать заказы, которые к ним не относятся. При этом покупатель «видит» только верхушку этого айсберга.

auto-market9

Например, участнику можно указать список автомобилей, по которым работает магазин или сервис, или категории запчастей. Тогда заявки на детали от других машин или других категорий приходить по системе не будут.

auto-market10

Зато подходящие по критериям запросы приходят очень быстро. И тут уже от сотрудника магазина будет зависеть оперативность ответа и его качество. Выслав заказчику соответствующее описание детали, её цену и фото максимально быстро продавец увеличивает свои шансы на сделку. Все запросы сохраняются в истории и доступны для анализа. Запросы в базе можно сортировать по дате поступления, конкретной запчасти, марке автомобиля и оператору.

auto-market11

Встроенная система анализа поступающих запросов дополнительно облегчает работу по анализу действий персонала, изучению спроса на какие-либо запчасти и работу маркетолога, например.

auto-market12

Вообще сразу можно заметить, что функционал приложения для участника гораздо шире и позволяет многое. Если хотите, можно создать счет для оплаты участия в системе.

auto-market13

Счет также отобразится в модуле «документы», наравне с другими документами.

auto-market14

Можно установить информацию о режиме работы предприятия. Это особенно важно делать потому, что клиент может указать в теме запроса критерий «работают сейчас». Ну и уехать в соседний магазин или сервис, который тоже работает круглосуточно или на выходных, а его оператор не поленился заглянуть в этот модуль

auto-market15

А можно еще устроить крутую рекламную кампанию, все там же, на сайте Auto-Market.kz Ведь где же еще ловить покупателей, как не на рынке?

Можно сказать, что данная система напоминает биржу, на которой продавцы с помощью предложения конкурируют друг с другом за решение покупателя. Выигрывает тот, кто быстрее всего предоставит уникальный продукт или уникальное предложение. Или это постоянно работающий, в чем-то стихийный, но при этом хорошо отлаженный промо-инструмент.

Кстати, об инструментах. Серверная часть всей системы реализована во фреймворке для создания веб-приложений ASP.NET (MVC 3). Мобильное API реализовано с использованием  Thrift, что существенно понизило затраты на проектирование, согласование и реализацию его поддержки в серверной и клиентских частях. Это особенно здорово сработало еще и потому, что мы сами разрабатывали как клиентскую, так серверную части. Приложение для участников разработано на базе нескольких библиотек наших собственных домашних заготовок(да, у нас есть своя CMS для бизнес-приложений! ).

Сейчас мы наблюдаем за развитием проекта и изучаем обратную связь от участников и заказчика. Надеемся, что система приживется. Кое-кто из наших разработчиков, набегавшись после ДТП по автомагазинам, уже мечтает о подобных ресурсах и у нас. Так что может и жаль, что это не наш бизнес – мы просто делаем крутые штуки на заказ.

Приложение для контроля работы тоннелепроходческого комплекса

Выпущенное Enterra в 2010 году приложение TMAP, контролирующее работу тоннелепроходческого механизированного комплекса (ТМК), подверглось очередному обновлению. Заказчик попросил немного изменить алгоритм контроля ряда параметров комплекса и ещё некоторые данные в отчетах представлять более подробно. Эта фраза, конечно, ничего толком не объяснит без небольшой лекции о том, как мы это приложение создавали. Впереди Вас ждет интересный рассказ о том, как устроено это приложение. Оно ведь является частью систем управления огромными и не очень ТМК производства компании HerrenknechtAG.

 

TMK1

Самый крупный в мире проходческий щит, диаметром 15,2 метра, построил в 2010 году заказчик нашего ПО, компания HerrenknechtAG. Он способен проходить за сутки до 22 метров. Его собирались использовать для прокладки автомобильного туннеля через центр Мадрида. Тоннель длиной 3650 метров строили, чтобы избавить столицу Испании от пробок. В таких вот ТМК и используется наше ПО.

TMK2

ТМК совсем не кажется маленьким на фоне горы, которую собирается прогрызть. Это квинтэссенция мощи человечества, мы гордимся тем, что нервная система таких машин работает на нашем приложении TMAP.

Немного истории

В конце 2009 года мы получили от немецкой компании HerrenknechtAG заказ на разработку программного обеспечения для систем контроля их огромных машин, которые пробивают тоннели по всему миру. Задача стояла нетривиальная. Дело в том, что целью приложения должны были стать сбор и визуализация данных, получаемых от тоннелепроходческого комплекса через OPC (OLE for Process Control) сервер. Необходимо было решение, которое сочетало бы в себе одновременно две системы: по сбору данных и визуализации. Но это только половина проблемы. Вторая её часть заключалась в необходимости иметь дело с огромным количеством датчиков – от двух до трех тысяч. Эти тысячи датчиков до десяти раз в секунду посылают из разных концов ТМК поток данных о сотнях параметров. В результате база данных, с которой программа должна иметь дело, быстро становилась необъятной.

Кроме перечисленного, надо было предоставить заказчику ещё и удобный пользовательский интерфейс, а также четкую архитектуру программного обеспечения. Достаточно высоким требованиям должно было соответствовать и само многоуровневое программное приложение с сервером специального применения. Связь между клиентом и сервером была реализована с использованием технологии .NET WCF.

Что получилось

Разумеется, чтобы создать ПО, наши специалисты с самого начала начали разбираться в том, как вообще работает ТМК. Например, выяснилось, что комплекс имеет стадии работы – он двигается, откачивает воду и грязь, бурит, удаляет продукты бурения, укрепляет пройденный участок кольцами бетонных тюбингов и так далее. В итоге программисты Enterra решили использовать это для элегантного решения проблемы роста базы данных с показателями работы ТМК. Решение приняли простое – программа обрабатывает данные по циклам работы, используя в качестве отсечки окончание установки тюбинга. После установки тюбинга начинается новый цикл и данные составляются в другой отчёт. В итоге формируются аналитические отчеты по кольцам с доступной детализацией по каждому кольцу.

TMK3
Так выглядит образец отчета «по кольцу», предоставляемый программой. Пользователь также может кастомизировать его в определенных пределах. Программа может производить их автоматически по завершении очередного цикла или выдавать по запросу.

В целом программа имеет следующий ряд особенностей:

  • защищенный от сбоев сервер, способный обрабатывать большое количество данных, получаемых с OPC сервера, и сохранять информацию в базе данных;
  • пользовательский интерфейс с виртуальной клавиатурой;
  • конструктор форм;
  • индикаторы;
  • разработчик отчетов с последующей их печатью;
  • графики средних (минимальный и максимальный) и текущих значений;
  • пользователь и управление правами пользователя;
  • многоязычный интерфейс;
  • настройки сервера;
  • отправка отчетов об ошибках по электронной почте.

TMK4
Вот так выглядит интерфейс окна индикаторов.

TMK5

А вот так можно это окно с индикаторами настроить.

Отдельно стоит упомянуть успешную реализацию разработчиками Enterra функции связи OPC. Все данные, полученные от проходческого щита, поступают на сервер OPC, а затем обрабатываются и визуализируются.

TMK6
Главные компоненты системы: OPC Server (Kepware’s COM server), RDBMS server (MS SQL 2005), Application server (.NET 3.5 Windows Service), Client application (.NET 3.5 WinForms application). Коммуникация между клиентом и сервером реализована с помощью технологии .NETWCF. Для визуализации данных и составления отчетов используется наш специальный продукт Perpetuum .NETModelKitSuite.

TMK7
Управление потоком данных от сенсоров.

TMK8

Пример визуализации показателей.



Видео работы системы
Дополнения

Ну вот, теперь фраза об алгоритме контроля ряда параметров комплекса и некоторых данных в отчетах приобретает смысл. В частности, в обновлениях по ряду показателей мы отказались от отсечки данных «по кольцам». Заказчик объяснил, что некоторые данные ему потребовалось получать по конкретным стадиям работы ТМК. Пришлось провести очень серьезную работу с базами данных и всей системой в целом, чтобы появились такие исключения.

Что касается детализации некоторых параметров, то заказчик попросил дать ему возможность отслеживать их в реальном времени почти по миллисекундам, что мы и сделали. Выглядит просто, да?

В общем, разработчики Enterra справились с усложнившейся задачей. Сейчас не так-то просто успешно реализовать проект с использованием новейших технологий Microsoft и своих знаний в. NET разработке с использованием компонентов для визуализации данных. Важно ещё и сопровождать этот проект впоследствии, отвечая на новые потребности заказчика. Что мы и делаем.

Параллельное программирование в .NET Framework 4.0

Денис Речкунов

В 4-ой версии фреймворка от Microsoft произведено множество улучшений в области параллельного программирования: были добавлены принципиально новые для .NET вещи и улучшены уже существующие механизмы, используемые разработчиками ранее.

С версии 4.0 во фреймворке дополнительно выделена отдельная библиотека для решения параллельных задач, так называемая TPL (Task Parallel Library), содержащая в себе высокоуровневые механизмы для выполнения, планирования и синхронизации параллельных действий.

Рассмотрим общий вид программы, использующей параллельные алгоритмы в .NET Framework 4.0:


netgif1
Figure 1 Parallel Programming in the .NET Framework (взято из MSDN)
Из схемы видно, что любая программа написанная .NET разработчиком и использующая параллельные алгоритмы в конечном итоге использует 3 модуля .NET Framework:

  • Data Structures for Coordination (набор потокобезопасных структур данных, примитивов синхронизации, реализаций паттернов параллельного программирования и управляемых оберток поверх потоков операционной системы)
  • Task Parallel Library (высокоуровневая библиотека параллельных задач, построенная поверх предыдущего модуля)
  • PLINQ Execution Engine (механизмы для высокоуровневой параллельной обработки данных, которые в конечном итоге реализованы поверх TPL)

Причем два последних модуля появились именно в .NET Framework 4.0, а первый был значительно улучшен с этой версии. Далее будет приведен краткий обзор перечисленных модулей.

Data Structures for Coordination

Все элементы этого модуля содержаться в пространстве имен System.Threading и их можно разделить на несколько групп:

  • Примитивы синхронизации (Semaphore, Mutex, Monitor, Barrier, ReaderWriterLock, LazyInitializer, SpinLock, SpinWait)
  • Средства для работы с потоками операционной системы (Thread, ThreadPool, ThreadLocal)
  • Атомарные операции (Interlocked)
  • Планирование действий (CountdownEvent, Timer)
  • Структуры данных для конкурентного использования (BlockingCollection, ConcurrentBag, ConcurrentDictionary, ConcurrentQueue, ConcurrentStack)

Semaphore

Класс реализует классический примитив синхронизации, который позволяет синхронизировать в себе заданное число потоков. Существует два основных действия – взять семафор (WaitOne) и освободить (Release). При создании семафора можно указать количество потоков, которые могут вызвать WaitOne без ожидания Release от другого потока, то есть, другими словами, сколько потоков могут брать семафор, до того как понадобится синхронизация. Помимо количества потоков можно указать глобальный идентификатор семафора в системе, то есть сделать семафор именованным, чтобы использовать его не в рамках одного процесса, а уже для межпроцессовой синхронизации. Для того чтобы получить именованный семафор (даже если он создан в другом процессе), достаточно использовать метод OpenExisting.

При использовании класса Semaphore необходимо учесть несколько особенностей:

  • У семафора нет идентификации потоков, то есть любой поток может освободить семафор, даже если он был взят другим потоком (по сути это просто увеличение/уменьшение счетчика внутри семафора).
  • Если, к примеру, два потока вызвали WaitOne, а затем один из них вызвал дважды Release, то когда второй поток попытается освободить семафор, получит исключение SemaphoreFullException.

Mutex

Также классический примитив синхронизации, по сути, является частным случаем семафора для заданного числа потоков равного 1, но с небольшим отличием. Используется для монопольного синхронизированного доступа к ресурсу. В отличие от семафора, Mutex идентифицирует потоки, которые занимают и освобождают его, таким образом освободить его может только тот поток, который его занял. Если же поток, занявший Mutex, завершился и не освободил его, то Mutex передается во владение следующему в очереди ожидания потоку и поднимает в нем исключение AbandonedMutexException.

Monitor

Еще один классический примитив синхронизации, по использованию аналогичен Mutex, однако, сам по себе Monitor не является объектом синхронизации и класс статический. Monitor’у необходимо указать объект, который будет являться признаком синхронизации. Для упрощенного использования мониторов в C# есть инструкция компилятора lock, которая организует блок кода, в котором гарантируется монопольный синхронизированный доступ к объекту, а также освобождение монитора после выхода из блока кода, даже в случае исключения.

Стоит помнить несколько особенностей Monitor:

  • Примитив работает исключительно со ссылочными типами
  • Не рекомендуется использовать публичные объекты для синхронизации, так как это может привести к взаимоблокировке
  • Рекомендуется везде, где это возможно использовать инструкцию lock вместо явного вызова методов класса

Barrier

Представьте, что вы менеджер проектов и у вас в распоряжении несколько сотрудников, которые занимаются решением каких-то задач. У вас появляется новая необъятная задача, которую можно начать только когда все ваши сотрудники закончат их текущие задачи. В таком случае вам нужен примитив синхронизации Barrier. Основная задача примитива зарегистрировать участников (AddParticipant), которые заняты своими задачами и по их завершению сообщают об этом и зависают (SignalAndWait) до тех пор, пока все участники не закончат свои задачи. Затем все потоки размораживаются и продолжают следующий «тур» своих задач по той же схеме, причем Barrier ведет счетчик этих самых «туров» или фаз.

LazyInitializer

Как очевидно из названия, класс выполняет задачу потокобезопасной ленивой инициализации объекта (EnsureInitialized(ref target)). Однако не стоит путать этот примитив с паттерном Singleton, так как класс не гарантирует, что объект будет создан всего раз, при конкурентном доступе к примитиву синхронизации может быть создано несколько объектов, но только один будет сохранен в target во всех потоках.

ReaderWriterLock

Реализация паттерна параллельного программирования, в котором ведется контроль доступа к объекту по схеме «Много читателей ИЛИ один писатель». Потоки, производящие чтение с объекта должны брать блокировку чтения (AcquireReaderLock), а при завершении процесса чтения снимать блокировку (ReleaseReaderLock), аналогично должны поступать и потоки-писатели (AcquireWriterLock, ReleaseWriterLock). ReaderWriterLock идентифицирует потоки, поэтому один поток не может взять два вида блокировки одновременно.

При использовании примитива необходимо учесть некоторые особенности:

  • Запись будет производиться, когда нет блокировок чтения, поэтому происходить это будет редко
  • Если запрос на блокировку не может быть удовлетворен, то поток получает ApplicationException.

SpinLock и SpinWait

Данные структуры используются для низкоуровневых блокировок и ожидания, не рекомендуется их использовать без необходимости, только если критична производительность, и вы подробно ознакомились со всей информации об этих структурах в MSDN.

Thread, ThreadLocal, ThreadPool

Thread – это .NET оболочка для потоков операционной системы, которая позволяет выполнять действие асинхронно и управлять его выполнением. Поддерживается приоритет выполнения, приостановка выполнения, прерывание, а также межпоточная синхронизация (вызов метода Join блокирует вызвавший поток пока поток, у которого метод вызван, не завершится).
ThreadLocal – предоставляет локальное для каждого потока хранилище данных. То есть если поток проинициализировал это хранилище какими-то данными, то они будут доступны только из этого потока, а в другом потоке объект будет не проинициализирован.

ThreadPool – идея пула потоков схожа с семафором: есть ограниченное число потоков которые могут существовать в пуле, каждому потоку предоставляется задача на исполнение, однако, когда поступает очередная задача (QueueUserWorkItem), а свободных потоков в пуле нет, задача ставится в очередь, пока какой-нибудь из потоков не освободится.

При использовании ThreadPool необходимо учесть несколько особенностей:

  • Все потоки в пуле являются фоновыми (Background = true)
  • Таймеры и зарегистрированные операции ожидания в .NET также используют ThreadPool
  • Для каждого процесса создается один пул потоков, который по умолчанию содержит 250 рабочих потоков на каждый процессор и 1000 потоков на завершение ввода/вывода
  • Когда все свободные потоки получают задачу, то для следующей задачи поток создается с задержкой 0,5 сек

Concurrent Collections

Из представленных структур данных особого внимания заслуживают, пожалуй, BlockingCollection и ConcurrentBag, остальные же коллекции являются лишь адаптированными для конкурентного использования ранее существующими коллекциями.

BlockingCollection

Задача этой коллекции предоставить ограниченное в размере хранилище, причем, если поток попробует записать в заполненную коллекцию, он будет блокирован, пока в коллекции не освободится место, а если поток попробует прочитать элемент из пустой коллекции, то он будет блокирован, пока там не появится хотя бы один элемент.

ConcurrentBag

Данная коллекция имеет высокую производительность за счет, того что не заботится о сохранении порядка добавленных в нее элементов, удобно использовать, когда вам необходимо собрать данные с разных потоков для отправки результирующего набора как параметр в следующий метод.

Task Parallel Library

Основным пространством имен для библиотеки является System.Threading.Tasks. Библиотека содержит высокоуровневые средства выполнения параллельных задач, в которых разработчику нет нужды задумываться о синхронизации, блокировках, создании и управлении потоками. Условно библиотеку можно разделить на две части:

  • Parallel – класс реализующий параллельный оператор цикла с его вариациями и метод Invoke для быстрого асинхронного вызова действия через Task.
  • Task, TaskFactory, TaskScheduler – классы связанные с планировкой и постановкой параллельных задач

Task

Класс Task является высокоуровневым аналогом класса Thread, однако на самом деле исполняется как делегат в ThreadPool. Помимо расширенных средств комбинирования и планирования задач Microsoft утверждает, что TPL эффективнее распределяет и контролирует ресурсы, использует в себе ThreadPool, усовершенствованный с помощью алгоритмов, которые оптимально подстраивают количество потоков. А также очевидным преимуществом является более гибкая обработка результатов и исключений в задачах.

При использовании Task необходимо учесть несколько особенностей:

  • Если задача возвращает результат, он помещается в свойство Result и доступ к нему синхронизирован с завершением выполнения задачи
  • Если во время выполнения задачи произошло исключение, оно будет вложено в AggregateException и помещается в свойство Exception, которое также синхронизировано, а также выставляется флаг IsFaulted.
  • Если есть потоки ожидающие поле Result, в них автоматические будет вызвано это исключение.
  • У одной параллельной задачи может быть множество подзадач, возможно построение древесной структуры задач.

При постановке задачи разработчик имеет возможность указать параметры ее исполнения TaskCreationOptions:

  • None – поведение по умолчанию
  • PreferFairness – Рекомендация для TaskScheduler планировать задачи максимально сохраняя приоритет по порядку постановки задач (раньше старт – раньше завершение).
  • LongRunning – Уведомляет планировщик, что задача будет исполняться длительное время, такие задачи не помещаются в ThreadPool.
  • AttachedToParent – Уведомляет планировщик, что задача присоединена к родительской задаче и помещается в локальную очередь родительской задачи а не в ThreadPool.

CancellationToken

Эта структура не что иное, как реализация паттерна параллельного программирования «Conditional Variable». В TPL принято использовать именно эту структуру для прерывания параллельных задач, ее поддерживают класс Task и механизмы PLINQ.

Доступ к структуре синхронизирован, вы можете передать ее в задачу и затем вызвать метод Cancel(), выставив состояние, что задачу необходимо отменить. При этом внутри задачи разработчик сам решает, когда проверить, что задача отменена и прервать ее. При этом нет нештатного завершения процесса обработки каких-либо данных, разработчик имеет возможность обработать прерывание задачи и подготовить штатное состояние (например, завершить итерацию цикла).


netfig2
Figure 2 Пример использования механизма прерывания задач в TPL

PLINQ

Помимо TPL в новой версии .NET Framework Microsoft решила развить LINQ и представила его параллельную реализацию – это PLINQ (Parallel Language Integrated Query). Знакомый .NET разработчикам LINQ обзавелся реализацией, позволяющей обрабатывать данные параллельно, не задумываясь о потокобезопасности, синхронизации, сборе результирующего множества из разных потоков, оптимальном размере подмножеств на которые разбиваются данные для параллельной обработки. PLINQ предоставляет высокоуровневые подходы к параллельной обработке данных, однако, при необходимости, предоставляет разработчику свободу самостоятельно конфигурировать основные параметры процесса, что делает PLINQ также достаточно гибким.

PLINQ может быть использован со всеми коллекциями .NET которые реализуют System.Collections.IEnumerable, так как в .NET Framework 4.0 появился класс методов-расширений ParallelEnumerable а в нем расширение AsParallel для IEnumerable, которое возвращает обертку над коллекцией типа ParallelQuery и позволяет с почти тем же интерфейсом что и LINQ работать с коллекцией параллельно. При этом данные разбиваются на сегменты, причем учитывается тип коллекции для оптимального разбиения, а когда нет возможности обработать данные параллельно автоматически используется последовательный режим. Как уже упоминалось, можно использовать CancellationToken для прерывания обработки коллекции.

Перед тем как все-таки использовать PLINQ, необходимо задуматься о накладных расходах механизма на сегментирование, сбор и упорядочивание данных, какова степень параллелизма вашей системы (сколько ядер/процессоров), достаточно большой ли у вас объем данных, чтобы обрабатывать его параллельно или все же дешевле будет обработать его последовательно. Важным фактором также является хорошее знание документации PLINQ, в которой описаны случаи, когда механизм начинает использовать последовательный режим. Если вы не доверяете сегментации, которая работает по умолчанию в PLINQ, вы можете использовать свой сегментатор, создав его методом Partitioner.Create.

Заключение

Без всяких сомнений в 4-ой версии .NET Framework проделана огромная работа, результат которой позволяет проще использовать параллельные алгоритмы и все преимущества многоядерных систем, которые установлены уже у большинства пользователей, а так как эти средства очень высокоуровневые это уменьшает вероятность ошибки при разработке приложения, работающего в нескольких потоках.

Видео с докладом по этой теме можно посмотреть здесь.

Новогодний марафон

“Каждый год, 31-го декабря, мы с друзьями ходим в баню” (с) Евгений Лукашин

Перефразируя популярную цитату героя Мягкова из кинофильма “Ирония судьбы, или С легким паром”, мы каждый год перед новогодним корпоративом устраиваем конкурс на самое лучшее новогоднее оформление кабинетов.

 

Как известно, в нашей компании несколько направлений и элементы новогоднего оформления кабинетов по традиции несут тематический характер.

Мобильные разработки

Как сообщает “мобильная” команда, уходящий 2012 год прошел под знаком iOS. О чем свидетельствуют записи тут, здесь, там и еще вот. И чуть не забыли про это.

 

При чем здесь Android?

– Пойдем простым логическим путем.
– Пойдем вместе.
(с) Ирония судьбы…

Логично, что за количественным преимуществом iOS-приложений, акцент в Новом году будет сделан на приложениях под Android.

Enterra Poker

Развитие платформы Enterra Poker продолжалось и будет продолжаться. В 2012 году, к существующим версиям (флэш версия, десктоп версия, социальная версия), мы предложили мобильную версию клиента.

Разумеется, на 2013 год обещано много нового. Команда разработчиков уже сейчас готовит подарки в виде новых версий платформы Enterra Poker, в которые войдут новые игры и продукты, игровые особенности и возможности, полезные функции и другие необходимые изменения.

Конкурсное новогоднее оформление было поддержано абсолютно всеми отделами и департаментами. Ниже представлена фотоподборка от Perpetuum Software, Адаптивных технологий, отделом Java и .NET разработок.

— Куда вы меня несете?
— Навстречу твоему счастью.
(c) Ирония судьбы…

Желаем удачи и процветания в Новом году, новых вершин в бизнесе и осуществления профессиональных планов.

С наступающим Новым 2013 годом, друзья! В Новый год вместе с Энтеррой!

 

Детальный обзор процесса разработки под Windows 8

Видео с семинара, посвященного разработке под Windows 8. Семинар проводился в рамках встречи барнаульского сообщества .NET разработчиков и при нашей поддержке.

Обзор языка F#

 

Обзор языка F#, состоявшийся в рамках встречи барнаульского сообщества .net разработчиков.


Подробности и анонсы новых встреч можно найти здесь