MCP

вторник, 27 октября 2009 г.

GAC

Не выдержал и решил написать ответ на вопрос про GAC для конкурса Гайдара про платформу.

Переписывать MSDN и Рихтера не буду, для разнообразия скажу своё мнение про GAC, чтобы ответ отличался от остальных.   Собственно расскажу, не про то, чем хорош GAC, а чем он плох.

Для начала в двух словах про него — это глобальный кеш сборок, и любое приложение, которое использует опредёленную сборку сначала посмотрит на её наличие в GACе, а только потом будет искать в других местах. Т.е. можно считать GAC банальным хранилищем DLLек, как Windows\System32, но с одним важным отличием. Сборки хранятся не по имении библиотеки, а по имени, Strong Name ключу, версии, культуре и платформе (x86, x64). Т.е. можно хранить разные версии сборок и даже умудряться их использовать в одном приложении (хотя лучше постараться не делать так). Т.е. GAC полезная функциональность, но есть несколько НО.

Самое главное, теряется возможность xcopy deployment, необходимо использовать gacutil или делать приличный Installer. Но если подумать, то что нужно класть в GAC? Нужно туда размещать библиотеку, которую будут использовать несколько приложений на компьютере, иначе особого смысла в этом нет. Другими словами, это должен быть конкретный shared-компонент. А кому нужен shared-компонент? Только разработчикам. Для обычных пользователей это в большинстве случаев не нужно. А разработчики очень не любят сложные процессы установки библиотек. Им бы в проект скопировать что надо, и не думать потом о библиотеках. В противном случае получается, что у разработчика может всё работать, ибо сторонняя сборка в GACe, а у клиента уже всё будет падать, ибо разработчик забыл её приложить к приложению.

Например, мой epic fail был с библиотекой Microsoft.mshtml.dll, которая оказалось что ставится со студией, и напрямую в приложении не используется, а используется через третьи библиотеки. В результате, у меня приложение работало на всех компьютерах, а половина клиентов ругалась. Конечно, я уже умный, и подобных вещей стараюсь не допускать, но вот пример как легко можно сломать приложение использованием GACа.

Собственно, если мы планируем использовать сборку в GACе, то у нас сразу усложняется разработка. Необходимо писать скрипты для билда, которые будут выковыривать сборку из GAC, компилировать новую версию и вставлять обратно. Вроде не сложно, но программисты ленивые, и обязательно что-нибудь схалтурят, и при деплое получим проблемы.  Ещё нужно обязательно использовать Strong Name, что на этапе разработки иногда плохо, ибо придётся раздавать ключ всем разработчикам (проблема в секурности), также сразу включается версионирование, которое менять нужно вручную. Иначе получатся две абсолютно разных сборки с версией 1.0.0.0, одна из которых в GAC, а вторая нужна приложению, и это вызовет замечательные проблемы, которые будет очень весело отлаживать.


Собственно, что я хотел сказать:

  • Использовать GAC нужно, когда есть проблемы с версионированием. Это позволит их решить. Например, приложение А использует библиотеки B и С. B использует библиотеку D версии 1.0.0.0, а C использует D версии 1.2.0.0. Как это это необходимо решать. Тут нужен GAC, ибо два файла с одним именем к приложению подцеплять плохо.
  • Использовать GAC нужно, когда есть много приложений, использующих одну сборку. Как вариант — хостинг многих приложений с общим компонентом. И то, может быть проще не использовать GAC, ибо места на диске не так уж и много сэкономится, а если случайно выкинут сборку из GAC, то можно получить проблемы.
  • Хороший пример того, что нужно класть в GAC — системные библиотеки .NET Framework
  • Во всех остальных случаях — не стоит. (Моё личное мнение).

.NET Remoting по протоколу SOAP. Возможно ли?

Тут @gaidar устроил конкурс и задаёт всякие разные вопросы.  В принципе, отвечать на них не планировал, ибо умные ответы писать долго и получится переписывание книжек/MSDN, а глупые можно и в Твиттере

Но, тут задали вопрос про Remoting, а это же моя любимая тема.

Собственно, Remoting может использовать любой канал, хоть голубиную почту, с сообщениями, закодированными морзянкой, этим он и отличается в лучшую сторону, но вопрос именно в том, что можно ли из подобного SOAP/Remoting сделать настоящий Web Service? Ответ сложный, с одной стороны — да, ибо можно использовать SOAP, с другой стороны, эти сообещия будут весьма страшными и заточенными под remoting-клиента, а не обычного Web-Service клиента. Собственно, проблема в том, что для веб-сервисов нужны  WSDL и XSD описания методов, а Remoting хоть и делает WSDL, но делает его для себя, и особо не смотрит на стандартные неймспейсы и типы.

Так что ответ: В принципе да. Но если вы хотите, чтобы клиентами были не только те же .NET приложения, то вам же придётся приложить множество усилий, чтобы использовать только базовые типы, не использовать CAO и эвенты, т.е. сильно урезать функционал Remoting, чтобы свести его к веб-сервисам. А оно вам надо? Гораздо проще тупо и использовать веб-сервисы для тех целей, когда они нужны, это проще и понятнее, а Remoting не использовать вовсе, не нравится он мне. 

пятница, 23 октября 2009 г.

RDC vs RAdmin/VNC

Иногда бывает нужно зайти удалённо на свой компьютер. С одной стороны стандартный RDP рулит, но он обычно создаёт новую сессию, так что получается две запущенные сессии — локальная и удалённая. А это весьма раздражает, ибо заводится весь авторан, да и задача часто бывает именно посмотреть что в конкретно творится, а не просто завести сессию.

Так что обычно для этого приходится использовать RAdmin или какой-нить VNC. У них есть хороший побочный эффект, что человек может работать за компьютером, а другие смотреть на это дело. Но когда нужно подключиться самому к себе, это часто мешает (неприятно, когда коллеги по работе могут смотреть чем ты сейчас занимаешься, а ты их не видишь и даже не знаешь про это ).

Но есть простое решение с RDP, которое многие не знают, но тем не менее, оно сделано именно для таких ситуаций — залогиниться именно в локальную сессию удалённо. Делается это просто, запускается клиент с соответствующим ключом:

mstsc /console

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

mstsc /admin

Работает он также как и предыдущий.

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

четверг, 3 сентября 2009 г.

Немножко про Reflection

Недавно проверял скорость работы Reflection в плане того, насколько оно медленное. Расписывать все случаи не буду, также не буду утверждать что все замеры корректные, просто немного данных для информации, чтобы вы знали, что ожидать от Reflection:

  • Вызов метода через рефлекшен отличается в зависимости от того, является ли метод public или private
  • Для public вызов метода где-то в 100-150 (!) раз медленнее, чем обычный вызов
  • Для private вызов медленнее где-то раз в 400-500 (!). Выводы делайте сами.
  • Время на вызовы GetMethodInfo относительно невелико, при этом, похоже это всё кешируется. Так что особо оптимизировать вызовы тут смысла нет
  • Если вы точно знаете сигнатуру метода, который берёте через рефлекшен (в качестве варианта, пнуть какой-нибудь приватный метод, или при использовании какого-либо варианта плагинов), то можно воспользоваться Delegate.CreateDelegate с указанием нужного типа, получить правильный делегат и его вызов будет таким же быстрым (возможно даже чуть быстрее, есть подозрение на использование call вместо callvirt), как и прямой вызов
  • Если точно не знаете сигнатуру, то можно использовать Delegate.DynamicInvoke но производительность будет примерно такая же, как и у чистого рефлекшена
  • Если хотите использовать Expression для генерации, в частности LambdaExpression то совет тот же. Используйте чётко типизированный .Compile() и получите почти идеальную производительность (где-то 1.5, но компиляция не очень шустрая). С учётом того, что экспрешены — достаточно могучий механизм, подобное стоит использовать. Есть интересные задачи, где они могут сильно облегчить жизнь, или даже сделать что-то особенное.

Ну вот, в общем и всё. Пока для меня остаётся открытым вопрос: "Как использовать преимущества делегатов без возможности указания нужного типа напрямую", чтобы получить хорошую производительность для рефлешкена. Смотрю в сторону DynamicMethod, но это уж больно серьёзная артиллерия (хотя производительность замечательная). 

среда, 5 августа 2009 г.

Как заполнить поле в базе рандомными значениями

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

Для тестов иногда бывает необходимо заполнить поле в базе какими-нибудь левыми значениями. Проблема в том, что обычная функция RAND() при апдейте возвращает одно и тоже значение, ибо оптимизатор её оптимизирует. Собственно, из этого есть выход, заключается он в том, что в RAND() надо передавать рандомный seed в качестве параметра. Вариантов несколько, я использую такой:

UPDATE Table SET Field=RAND(abs(convert(varbinary, newid()) % 65536))*1000 

1000 — это максимальное значение в поле (точнее 999). Т.к. точность не требуется, особо над распределением не заморачивался. Пользуйтесь, если вдруг пригодится.

вторник, 28 июля 2009 г.

Windows Live Sync

По совету хорошего человека решил попробовать данную программу. Соответственно хочу поделиться краткими впечатлениями о её использовании.

Для начала, что она умеет:

  1. Выбирать папки для синхронизации и синхронизировать их между любым разумным количеством компьютеров. Т.е. вы просто кидаете туда файлы, а через некоторое время на другом компьютере они появляются.
  2. Синхронизировать файлы по запросу. В этом случае на другом компьютере появится заглушка с расширением p2p, при попытке открытия которой, будет скачан файл
  3. Загружать любые файлы с любого вашего компьютера через браузер (если разрешено).  Т.е. если вы дома забыли важный файл, теперь можно просто его снянуть через эту службу (раньше я использовал RDC/VNC для подключения к домашнему, и дальше вытягивал файлы).
  4. Расшаривать некоторые папки между выбранными пользователями. Т.е. нельзя расшарить папку для "всех" или для определённой группы. Можно только ввести email человека, которому нужно дать доступ к папке.

Теперь о том, как она это делает:

  • Необходимо залогиниться в Windows Live
  • Программа попытается открыть какой-нибудь из следующих портов: 80, 443, 6571, 8000 для того, чтобы другие компьютеры подключались напрямую к этому и забирали файлы
  • Используется шифрованное peer-to-peer соединение. Т.е. ваши файлы никуда не уходят. Сервер используется только как главное звено для обнаружения соседей.
  • Как я понял, если программа н;е смогла открыть порты, то синхронизация будет работать только в одну сторону, или же очень плохо.
  • Детали синхронизации не выяснял. Похоже файлы синхронизируются целиком. Коллизии тоже пока не рассматривал, не думаю что это очень принципиально для простого использования. Я для сложного всегда лучше самому всё протестировать, а не слушать чужое мнение.  

В общем, весьма неплохо. Конечно, хотелось бы ручного выбора портов, ибо у меня есть некоторое количество компьютеров за NAT-ом, и хотелось бы использовать синхронизацию между ними. А с учётом того, что практически доступно всего 2 порта (вы думаете у программиста есть бездействующие 80-ый и 443-ий порт? ). Так что для этого она не очень хорошо подходит.

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

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

Также, очень смущает то, что нет привязки к SkyDrive, хотя дизайн на сайтах похож, и вообще, это очень хорошо напрашивается в качестве онлайн-службы для бекапов. Ладно, можно и поискать программы, делающие из SkyDrive виртуальный локальный диск,  возможно Gladinet хорошо подойдет для этого. Кроме того, не рекомендуется синхронизировать pst-файлы и базы данных, ибо они хорошо меняются и обещают ошибки из-за этого.

Теперь о других подобных службах, я нашёл DropBox и Syncplicity. Как я понял, они пускают синхронизацию через свой сервер и хранят там файлы. Т.е. могут использоваться в качестве простенького Source Control'а, да и пофункциональнее будут. Но в них есть ограничение на объем доступной шары. после этого хотят абонентскую плату. Тут же никаких ограничений нет и файлы никуда не ходят. Да и в плане безопасности Майкрософту можно доверять (тапками не кидаться, но Майкрософту в этом плане я доверяю гораздо больше чем большинству других сервисов).

Ну, в общем-то и всё. Собственно писать про этот сервис особо нечего, он работает или не работает, никаких сложностей. Весит установочный файл всего 1.4 Мегабайта, берётся с соответствующего сайта и в принципе, может использоваться on-demand. Т.е. поставили на одном компьютере и забыли. Потом вспомнили, поставили на другом, настроили всё в браузере и давай синхронизировать. Теперь даже не нужна флешка для того, чтобы всё своё носить с собой. Можно выложить в папку и иметь на всех компьютерах одно и тоже. Лишь бы был интернет.

понедельник, 6 июля 2009 г.

Очередное российское интернет-издевательство

МОСКВА, 19 июня. /ПРАЙМ-ТАСС/. Регистрация доменных имен в зонах RU и РФ при обязательном предоставлении паспорта начнется с 1 октября 2009 г. Об этом сообщила пресс-служба регистратора RU-CENTER.

На заседании совета Координационного центра домена RU (http://cctld.ru/ru/), состоявшемся 17 июня, было принято окончательное решение о так называемой "паспортизации Рунета": теперь при регистрации доменных имен в зонах RU и РФ пользователь обязан предоставлять регистратору паспорт.

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