Программирование

воскресенье, 2 апреля 2017 г.

Мой опыт приобретения сертификата MCSD: App Builder

Введение

Всегда хотел получить формальное подтверждение своих знаний в области разработки на платформе .NET, но ленился и откладывал на потом. Нужны ли сертификаты — вопрос дискуссионный. Лично я решил, что официальное признание моих компетенций будет хорошим дополнением к моему опыту веб-разработки. Вместе с тем хотел заполнить пробелы в моих знаниях, которые были просто потому, что не требовались для решения текущих задач. Чтобы заставить себя готовится к экзаменам, приобрёл сразу 6 ваучеров "всё включено". Каждый ваучер предоставлял право на сдачу экзамена, четыре пересдачи (!) и доступ к тесту на measureup.com. Срок действия ваучера 6 месяцев с момента приобретения. Срок доступа к тренировочному тесту — месяц с момента применения ключа. За все ваучеры я заплатил около 50 т. р. Я планировал сдавать по экзамену в месяц, но всё вышло совсем по-другому :). В любом случае, сгораемый ваучер — очень веская причина не забрасывать подготовку к экзамену.

Английский язык

Прежде всего, без знания английского на экзамене делать нечего. Если вы можете понять нижеупомянутые книги и тестовые вопросы с минимальным использованием словаря (допустим, одно слово на страницу), то языкового барьера нет, к экзамену в языковом плане вы готовы. На экзамене нельзя пользоваться каким-либо переводчиком или словарём (ни онлайн, ни в виде бумажной книги).

Путь к получению сертификата

Один из способов получения MCSD: AppBuilder — получение MCSA: Web Applications и сдача дополнительного экзамена из списка на выбор.

Экзамены для получения сертификата MCSA: Web Applications:
  1. Exam 70-480: Programming in HTML5 with JavaScript and CSS3
  2. Exam 70-486: Developing ASP.NET MVC Web Applications
Дополнительный экзамен, который выбрал я:
  1. Exam 70-487: Developing Microsoft Azure and Web Services

Главный язык программирования на .NET — C#, и для начала я хотел получить подтверждение своих навыков программирования на C#. Для этого есть экзамен Exam 70-483: Programming in C#. Его я и сдал первым.

Книги для подготовки

Для всех упомянутых экзаменов есть книги, специально выпущенные в помощь к подготовке. Это книги из серии "Exam Ref ###" (### — код экзамена) с обложкой салатового цвета. Они стоят денег, но можно найти торрент-редакции изданий. Эти книги не содержат всех знаний, которые нужны для прохождения экзамена, но всё равно они крайне полезны. На веб-странице с описанием каждого экзамена перечислены его разделы, знания которых проверяются на экзамене. Так вот, эти учебники составлены строго в соответствии с разделами — главы соответствуют им по названиям. Также авторы подсказывают на что обратить внимание, возможен ли вопрос из этой темы или нет. Чаще всего пишется, что вопрос(-ы) из этой темы точно будут на экзамене, а вот из этой темы маловероятно. Самый большой минус книг Exam Ref — устаревание. Технологии постоянно совершенствуются, экзамены подстраиваются под изменения — одни вопросы заменяются другими, добавляются новые темы и т. д. Учебники же редко переиздаются. Ещё я столкнулся с откровенной некомпетентностью в книге Exam Ref 70-480. Например, автор утверждает, что в JavaScript возможна перегрузка функций. Также в книге описаны вещи, присущие только IE. По поводу других книг могу дать совет: абсолютно точно не нужно прочитывать все книги, которые соответствуют темам экзамена. Можно ограничится MSDN плюс какая-то хорошая книга, которая затрагивает большинство тем. Например, для 70-486 есть отличная книга "Pro ASP.Net Core MVC" от Freeman.

Тренировочные тесты

Большую помощь мне оказали тренировочные тесты на measureup.com. Они призваны имитировать настоящие экзамены, но я использовал их по-другому. На каждый экзамен у measureup есть ограниченное множество вопросов (~120-180), из которых конструируется тренировочный тест. Его можно гибко настроить — указать области тестирования, общее количество вопросов, время на тест и т. д. Я же делал так: выбирал абсолютно все вопросы, отключал рандомизацию порядка, убирал ограничение по времени и делал возможным увидеть правильный ответ по требованию. Далее запускал этот тест и по порядку отвечал на вопросы в режиме "ответил — проверил ответ". Основная польза measureup в том, что помимо указания правильного ответа, даётся объяснение почему этот ответ правильный, и почему остальные ответы неправильные. В конце объяснения приведены прямые ссылки на соответствующую документацию MSDN и иногда на чей-то блогпост. Это серьёзно "прокачивает" знания в соответствующей теме. У этих тестов тоже есть минусы — встречаются опечатки в коде, сам код плохо форматирован и нет подсветки, трудно читать. В тренировочных вопросах для экзамена 70-486 встречаются вопросы из мира WebForms. Лично мне не встречались вопросы по WebForms на настоящем экзамене, и вряд ли они там будут.

Центр тестирования

Выбирайте большой центр тестирования, чтобы иметь больше выбора во времени назначения тестирования. Также в больших центрах лучше оборудование. Первые экзамены я сдавал в маленьком центре, который предлагал всего два дня на неделе для тестирования. Я выбрал его, потому что он был расположен к моему дому ближе всех остальных. В последний раз, когда я в нём тестировался, три раза пропадало электричество. Никаких ИБП не было, компьютер после выключение ещё и не запускался. Время тестирования, к счастью, приостанавливалось, но всё равно все эти накладки не добавляли уверенности. После этого я сменил центр. Рекомендуемый московский центр могу написать в личном сообщении. Также есть возможность сдавать экзамены дома. Экзамены Microsoft дома не сдавал, ничего по этому поводу сказать не могу.

Сдача экзамена

Про саму сдачу экзаменов написано очень много. Содержание вопросов и ответов раскрывать не имею право. С собой ничего кроме паспорта брать нельзя. Часы, телефоны и браслеты необходимо оставлять в сейфе. Вам дадут планшет для записей, который необходимо вернуть сразу после тестирования. В экзаменах Microsoft больше всего мне нравится то, что результат отображается сразу после окончания тестирования, а именно: общий score, passed/not passed, % по разделам экзамена. Испытываю разочарование от того, что не показываются вопросы с ошибочными ответами. Мне очень хочется сделать работу над ошибками, но увы. Можно только постараться запомнить вопросы, которые вызвали затруднение, и потом дома почитать материалы на их тему. С другой стороны, я понимаю, почему так делается. Экзамены "многоразовые", если начнётся раскрытие информации о вопросах и ответах, то тесты потеряют свою ценность.

понедельник, 3 марта 2014 г.

Сравнение: event vs delegate

И делегаты, и события позволяют реализовать шаблон проектирования Наблюдатель. В чём же различие? Если в одном предложении, то событие — это надстройка на делегатом, которая сильно урезает его "в правах".
  1. Событие нельзя объявить свойством, только полем. Однако событие поддерживает определение своих методов подписки и отписки (add и remove) в стиле свойств.
  2. Реализация подписки и отписки на событие потокобезопасна (речь идёт о штатных методах add и remove).
  3. Полю события нельзя присвоить null вне другого класса. Вообще, стороннему коду нельзя ничего сделать с полем события кроме как подписаться или отписаться. Для этого используются операторы += и -=, которые транслируются в вызов add и remove. Оператор = к событиям не применим.
  4. Запускать событие напрямую можно только в том классе, в котором оно объявлено. Даже в потомках нельзя. Однако это можно сделать через метод-обёртку.
По мотивам топика на Хабре.

пятница, 28 февраля 2014 г.

Ошибка в переводном 4-м издании "CLR via C#" Рихтера

В примере кода, который находится в разделе "Уведомление о событии, безопасное в отношении потоков" (с. 291), использован устаревший метод Thread.VolatileRead() вместо Volatile.Read().

В оригинальном издании всё правильно — везде используется Volatile.Read(). В разделе упоминания этих методов чередуются, так что судя по всему это результат "недоправки" листингов с предыдущих изданий. Больше нигде в книге Thread.VolatileRead() не упоминается. Про Thread.VolatileRead() и Volatile.Read() можно начать читать отсюда.

вторник, 11 февраля 2014 г.

Неработающий XAML-дизайнер Visual Studio 2013 в проекте для Windows Store

При попытке запуска дизайнера XAML-страницы проекта для Windows Store получаю такое исключение:

System.Runtime.InteropServices.COMException
Это приложение не поддерживает указанный контракт или не установлено. (Exception from HRESULT: 0x80270254)

Для информации: среда разработки Visual Studio 2013 Ultimate установлена на Windows 8.1 Pro x64.

Это ошибка появляется при открытии дизайнером XAML-страницы именно для Windows Store. В обычном WPF-проекте ошибки нет, в проекте для Windows Phone — тоже. Начал гуглить. Чтение форумов не помогло. Сделал Repair установки — ошибка не исчезла. Видимо, дело не в повреждённых файлах или настройках.

Моя рабочая учётная запись (в которую я обычно загружаюсь) имеет права рядового пользователя Windows 8. Среду Visual Studio 2013 я привык запускать с правами администратора. Например, чтобы иметь возможность присоединяться к процессу IIS для отладки.

По опыту знаю, что запуск программы с правами администратора — это не одно и тоже, что и запуск программы в загруженной учётной записи администратора. Поэтому решил загрузиться в учётную запись администратора и открыть дизайнер там. Дизайнер открылся без ошибок. Это меня расстроило, т. к. мне не хотелось всякий раз загружаться как администратор, когда мне необходимо программировать. На всякий случай решил попробовать открыть дизайнер в студии, запущенной в рабочей учётной записи без дополнительных привелегий. Дизайнер открылся без ошибки! Такое поведение для меня выглядит странным. Другого решения я не нашёл. Установка Update 1 для VS 2013 не помогла. Если у кого-то в такой же ситуации дизайнер работает без ошибок, был бы признателен за отклик.

понедельник, 10 февраля 2014 г.

Доступ к непубличным экземплярным полям класса

К непубличным экземплярным полям класса можно обращаться из другого экземпляра того же класса. Следующий код компилируется без проблем.
class PrivateFieldsAccess
{
    private int privateField;
    protected int protectedField;

    public PrivateFieldsAccess(PrivateFieldsAccess instance)
    {
        privateField = instance.privateField;
        protectedField = instance.protectedField;
    }

}
Модификаторы доступа определяют доступ к членам класса, а не экземпляра. Другими словами, ограничение доступа к членам класса служит для инкапсуляции и снижения зависимости между кусками кода, а не снижения зависимости объектов в памяти во время выполнения.

пятница, 19 апреля 2013 г.

Ловушки при использовании Response.Filter

ASP.NET позволяет через свойство HttpResponse.Filter выполнять манипуляции с контентом перед отправкой его клиенту. Под контентом понимается html-разметка, css-стиль, js-код и вообще любые данные, отправляемые веб-сервером в ответ на запрос. Для чего это нужно? Например, для замены в теле ответа одного текста на другой. Подробно расписывать как это делать я не буду, а покажу очень важные особенности, которые необходимо учитывать при реализации продобного рода фильтров.

Первая ловушка — отдаваемый сервером контент разбивается на порции. Приведу типичный код, встречающийся на просторах интернета, который заменяет текст:

public class HtmlFilter : Stream
{
    // Второстепенный код пропущен.

    //  Основной метод, производящий замену текста перед записью в поток.
    public override void Write(byte[] buffer, int offset, int count)
    {
        Encoding encoding = HttpContext.Current.Response.ContentEncoding;

        string s = encoding.GetString(buffer);
        
        s = Regex.Replace(s, pattern, replacement);
        
        byte[] outData = encoding.GetBytes(s);
        
        _baseStream.Write(outData, 0, outData.Length);
    }
}

Чем примечателен этот код? Тем, что он неправильный. Контент разбивается на порции, и эти порции записываются в поток по отдельности — метод Write() вызывается несколько раз. Это значит, что иногда в отфильтрованном контенте будут присутствовать незаменённые экземпляры искомого текста, которым "посчастливилось" попасть на границы порций, а значит Regex просто не найдёт и не заменит их. Самое плохое в этой ошибке то, что она выглядит как случайная, её очень сложно воспроизвести. Вероятность её проявления прямо пропорционально величине заменяемого текста (pattern'а). Чем он больше, тем вероятней то, что он окажется на границе порций контента. В моём случае заменяемый текст являлся частью URL, и мне даже удалось увидеть один "неправильный" URL.

Окей, как же тогда правильно заменять текст в контенте? Основной принцип — склеивать порции, потом анализировать их вместе, и после этого писать в поток и отсылать. На эту тему есть замечательный пост Рика Страла (Rick Strahl). Он реализовал удобный класс-фильтр, который решает эту проблему.

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

четверг, 20 декабря 2012 г.

.NET Framework 4.5 — это лишь апдейт для 4-й версии

Заглянул на рабочем компьютере в каталог C:\Windows\Microsoft.NET\Framework и не увидел в нём каталога с названием, начинающимся на "v4.5". После поиска информации в Гугле, у меня сложилось впечатление, что Майкрософт собрала все обновления для 4-й версии, добавила несколько фич в язык C# и выпустила это под громким названием .NET Framework 4.5.
  1. 4.5 ставит себя в каталог v4.0.30319, предназначенный для 4-й версии. В MSDN написано, что "сборки заменяются" (the assemblies are replaced).
  2. Этот пункт вытекает из предыдущего — на компьютере не могут быть одновременно установлены обе версии, только одна из них. Это принципиально отличается от предыдущих выпусков, когда версии 1.0, 1.1, 2.0, 3.0 и 3.5 живут на компьютере бок о бок. Чтобы вернуться к 4-й версии, 4.5 необходимо полностью удалить.
  3. Версии файлов сборок отличаются лишь последней группой цифр:
  4. Новые ключевые слова C# — async и await — можно использовать и в 4-й версии при установке соответствующего обновления.
  5. Пожно скомпилировать программу для версии 4.5, и она будет работать исправно в среде 4-й версии, но до тех пор, пока не попытается воспользоваться особенностями, присущие только версии 4.5.
  6. В IIS нельзя выбрать среду исполнения ".NET Framework 4.5" у пула приложений — только 2.0 или 4.0.

Источники

  1. http://www.west-wind.com/weblog/posts/2012/Mar/13/NET-45-is-an-inplace-replacement-for-NET-40 — наиболее полное изложение по теме
  2. http://msdn.microsoft.com/en-us/library/5a4x27ek.aspx

вторник, 25 сентября 2012 г.

Сравнение: const vs readonly

Таблица различий между полем-константой и полем только-для-чтения в C#
Аспект const readonly
Место инициализации Только при объявлении поля. При объявлении поля, в конструкторах экземпляра, в статическом конструкторе.
Время инициализация При компиляции. При создании экземпляра класса или при обращении к статическим членам класса.
Поддерживаемые типы Boolean, Char, Byte, SByte, Intl6, UIntl6, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, String и enum. Использовать ссылочные типы как константы не имеет смысла, т. к. единственное допустимое начальное значение таких констант — null. Исключение — тип String. Любой тип.
Способ хранения Хранится в метаданных сборки. Везде, где встречается константа, компилятор вставляет вместо неё само значение. В период выполнения память для неё не выделяется. Хранится как обычное (instance) поле с выделением памяти в период выполнения.
Разделение между сборками Везде, где встречается константа, определённая в другой сборке, компилятор вставляет вместо неё само значение из сборки. После компиляции, сборка с константой более не требуется для выполнения приложения (при условии, что используется только константа). Если константа будет изменена, то для использования нового значения в других сборках потребуется их перекомпиляция. Разделяется как обычное поле. Сборка с reaonly полем должна присутствовать в списке ссылок у сборок-клиентов.

Источники

  1. http://msdn.microsoft.com/ru-ru/library/acdd6hb7.aspx.
  2. Дж. Рихтер. CLR via C#. Программирование на платформе Microsoft .NET Framework 4.0 на языке C#. – С. 191.

воскресенье, 23 сентября 2012 г.

Сравнение: Mumble vs Skype в играх

Никогда не думал, что придётся делать такое сравнение, т. к. для меня очевидно то, что Скайп плохо подходит для общения во время игры. Меня удивляет упорное использование Скайпа среди молодых игроков. Зачастую они просто не знают об альтернативах. А когда узнают про Мамбл, то они по различным причинам не желают эту программу использовать. Чаще всего ребятам лень разбираться в настройках Мамбл. Возможно, скайпоюзеры что-то слышали про Тимспик (TeamSpeak) или Вентрило (Ventrilo). Так вот, Мамбл — более функциональный аналог. Если не слышали про такие программы, могу определить ещё Мамбл как голосовой аналог IRC (текстовый интернет-чат). Если всё равно непонятно, отсылаю к статье Википедии.

Скайп предназначен прежде всего для совершения [видео]звонков и звонков на телефонные номера. Мамбл — средство для коллективного фонового общения. Я не буду рассматривать видеозвонки, т. к. это не относится к теме. Прежде всего, у этих программ разные подходы взаимодействия с пользователем. Скайп предполагает, что во время разговора пользователь ничем другим заниматься не будет, т. е. внимание будет сфокусировано на окошке Скайпа. Мамбл же создан для фонового общения во время занятия основным делом — игрой.

Я не буду описывать все возможности Мамбла и руководство по его настройке. Я просто сравню две программы по пунктам.

Аспект Mumble Skype Коментарий

Важные во время игры

Время задержки Очень низкое: счёт идёт на миллисекунды Высокое: секунда и даже выше Время задержки очень важно в динамических играх. Необходимо, чтобы команды быcтро доходили до партнёров. Задержка на секунду может стоить фрага.
Позиционирование голоса Да Нет
Уменьшение громкости Да: во время разговора громкость звука из других источников уменьшается Нет
Отображение собеседников в играх (оверлей) Да Нет Полезно видеть, кто находится в комнате.
Функция "нажать-чтобы-говорить" Да Нет
Настройка горячих клавиш Да Нет
Плагины (для интеграции с играми) Да Нет

Функции коллективного общения

Способ организации Комната Конференция
Количество участников Неограниченно До 25
Присоединение к разговору без приглашения Да Нет Не нужно кому-либо отвлекаться, чтобы пригласить ещё одного участника. Пользователи могут свободно входить и выходить из комнаты, при условии, что правильно настроены соответствующие списки доступа.
Приглушение себя (только слушать) Да Нет Оставаясь в виртуальной комнате, можно не беспокоиться, что вас кто-то услышит.
Полное отключение себя (только получать сообщения) Да Да (отключение от конференции) Полная звуковая изоляция от участников.
Приглушить собеседника для всех Да Да (отключение от конференции) "Мягкий бан". Пользователь может находиться в комнате, но его никто не услышит, и сам он ничего не услышит.
Сигнализация о состоянии собеседников (говорит/не говорит, приглушён) Да Нет Полезная функция, показывающая кто говорит.
Текстовый чат Да Да

Средства безопасности

Шифрование трафика Да Да
Контроль доступа Да Нет Список контроля доступа — мощная функция, с помощью которой можно определить, кто может заходить в комнату, а кто не может.

Прочие

Необходимость регистрации Нет Да
Простота установки и настройки Нет Да
Мультиплатформенность Да: Windows, Linux, Mac OS X Да: Windows, Linux, Mac OS X
История сообщений Нет Да
Журнал разговоров Нет Да
Работа в закрытой локальной сети Да Нет
Поддержка клавиатуры Logitech G15 Да Нет
Поддержка прокси Да Да
Сетевая архитектура Клиент-серверная Пиринговая (P2P)

Одна из самых замечательных возможностей Мамбл — позиционирование голоса в зависимости от положения говорящего на карте в игре. Ещё очень удобен оверлей — краткая информация обо всех присутствующих в разговоре, которая отображается в играх во время игры. На сколько я знаю, оверлей доступен только для Windows-версии.

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

Скачать Мамбл можно с официально сайта.

среда, 19 сентября 2012 г.

Сравнение: abstract class vs interface

Представляю вольный и дополненный перевод таблицы из статьи на CodeProject.

Таблица различий между абстрактным классом и интерфейсом в C#

Аспект abstract class interface
Назначение Как любой базовый класс, представляет ядро поведения для всех наследников. Если в абстрактном классе не реализован ни один метод, имеет смысл превратить его в интерфейс. Контракт, ничего более. Интерфейсы часто используются (и во основном предназначены для этого) как примеси без реализации при проектировании иерархии классов.
Реализация по умолчанию Может быть частично или полностью реализован, предоставлять базовую функциональность. Не может содержать какой-либо код.
Модификаторы доступа членов Члены могут иметь все допустимые модификаторы доступа. Только public.
Наследование Наследование от абстрактного класса реализует отношение "является". Наследование от интерфейса определяет отношение "реализует".
Множественное наследование Класс может наследовать только один класс. Класс может наследовать несколько интерфейсов. При этом он может и не реализовывать методы интерфейса, т. е. быть абстрактным. Сам интерфейс тоже может наследовать несколько интерфейсов.
Скорость Быстро. Требуется больше времения для поиска реализованного метода в соответствующем классе.
Расширение При добавлении нового метода в абстрактный класс, мы можешь реализовать его, тем самым не нарушив работу наследующих классов. Если тело метода оставить нереализованным, потребуется его реализация в классах-наследниках с последующей перекомпиляцией. При добавлении нового метода в интерфейс мы должны определить его во всех классах, реализующих интерфейс, с перекомпиляцией.
Члены Может содержать все допустимые члены. Не может содержать константы, поля, операторы, конструкторы экземпляров, деструкторы или типы. Допускаются: методы, свойства, события, индексаторы (свойства с параметрами).
Статические члены Может содержать статические поля и методы. Не может содержать статические поля и методы.

Источники

  1. http://www.codeproject.com/Articles/11155/Abstract-Class-versus-Interface
  2. http://msdn.microsoft.com/ru-ru/library/ms173156.aspx
  3. Э. Гамма, Р. Хелм, Р. Джонсон, Д. Влиссидес. Приемы ООП. Паттерны проектирования.
  4. Дж. Рихтер. CLR via C#. Программирование на платформе Microsoft .NET Framework 4.0 на языке C#. — С. 322.
  5. Дж. Либерти. Программирование на C#.

суббота, 1 сентября 2012 г.

Проблемы при установке Async CTP v3

Я решил попробовать новое средство асинхронного программирования от Microsoft — Visual Studio Asynchronous Programming. Это расширение идёт вместе с C# 5 в составе Visual Studio 2012, а для Visual Studio 2010 есть пакет под названием Async CTP v3.

Скачал дистрибутив и запустил установку. Установка прошла без каких-либо видимых проблем. Однако, я не обнаружил каталога Microsoft Visual Studio Async CTP в My Documents. Погуглив, обнаружил, что это расширение конфиликтует с Silverlight 5 SDK и некоторыми обновлениями. Итак, если вы хотите корректно установить Async CTP v3 необходимо сделать следующее:

  1. Удалить предыдущую верию Async CTP (v1 или v2). Если у вас "недоустановленная" версия v3, то её тоже необходимо удалить.
  2. Удалить Silverlight 5 SDK.
  3. Установить все обновления в Центре обновления Windows. Ещё рекомендуют также установить и необязательные обновления, но тут без фанатизма.
  4. В установленных обновлениях найти и удалить следующие:
    • KB2549864
    • KB2615527
    • KB2635973
    • KB2645410
  5. Запустить и установить Async CTP v3.

Первый признак того, что установка прошла корректно — информационное окно, появляющееся при завершении установки:

Ещё нужно проверить версии всех четырёх файлов:

  1. C:\Windows\Microsoft.Net\Framework\v4.0.30319\csc.exe
  2. C:\Windows\Microsoft.Net\Framework\v4.0.30319\vbc.exe
  3. C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\msvbide.dll
  4. My Documents\Microsoft Visual Studio Async CTP\Samples\AsyncCtpLibrary_Phone.dll

Правильные версии этих файлов:

Async CTP v3
csc.exe 4.0.30319.517
vbc.exe 10.0.30319.517
msvbide.dll 4.0.40219.355
AsyncCtpLibrary_Phone.dll 1.1.0.0

Как узнать версию файла: щелчок правой кнопкой по файлу -> Свойства -> Подробно.

Источники

  1. http://blogs.msdn.com/b/lucian/archive/2011/11/01/async-ctp-v3-installation.aspx
  2. http://mikaelkoskinen.net/post/async-ctp-fix-installation-problem.aspx