Сообщения

Сообщения за 2007

Полезные мелочи

Как-то на днях надо было повозиться с XPath и Xslt и для быстрой проверки XPath запросов искал небольшую утилитку. Попробовал несколько и остановился на VisualXPath , ее и хочу порекомендовать. И несмотря на удобную фичу по отладке xslt, которая появилась в VS 2005 стал пользоваться VisualXPath регулярно. Среди плюсов ходчу отметить, всесьма простой интерфейс, коррекно работает с namespase, xml исходного документа и результата запроса отображается в древодвидной структуре с раскраской синтаксиса (как в IE, врезультате немноготормозит при открытии больщих файлов, но весьма удобно при анализе). Может помочь построить несложный XPath запрос. Проект VisualXPath для VS 2003 любезно выложен автором с иходным кодом.

Шах и ... пат

На днях пытался устранить предупреждение компилятора по использованию устаревших методов Thread . Suspend и Thread . Resume . Привожу его: “ Thread.Suspend has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. .. .” Фрагмент кода, где используются устаревшие методы, выглядит приблизительно так: //... thread.Suspend(); try { StackTrace stackTrace = new StackTrace (thread, false ); //... } finally { thread.Resume(); } //... В MSDN -документации к конструктору StackTrace ( Thread targetThread , bool needFileInfo ) сказано, что передаваемый поток должен быть в состоянии Suspended , иначе возникнет ThreadStateException. Небольшой эксперимент подтвердил, что MSDN находится в актуальном с

Unable to attach to the process

Изображение
Вот такое сообщение я получил от студии, когда попытался подключиться к IE, чтобы отладить панельку, написанную на C#. Кстати, хорошая и почти единственная статья о том, как сделать свой тулбар для эксплорера, написана вот здесь: Extending Explorer with Band Objects using .NET and Windows Forms . А теперь - детально. Панель для эксплорера представляет собой так называемый COM Callable Wrapper (CCW) и была написана на .NET 1.1 в Visual Studio 2003 - аттачился я, соответственно, в ней же. Как вы уже поняли, такой способ не сработал. Затем я попытался отладить компонент при помощи другого хост-контейнера (ActiveX Control Test Container) – та же ерунда. Думаю, ладно не студия, так WinDbg. Пусть не так удобно, но на безрыбье и рак рыба. Приатачился! Собирался подгрузить SOS.dll и тут обратил внимание, что в процесс IE загрузился не .NET 1.1 a .NET 2.0! Снес с машины второй фреймворк (к счастью, у меня была такая возможность). И опа! - все хоккей, студия замечательно подключилась. По правд

События и многопоточный код

Недавно, просматривая главу книги Framework Design Guidelines, посвященную событиям (event) наткнулся на интересное замечание. Это же замечание про события процитировано и на блоге Brad Abrams Events, Delegate and Multithreading . Суть его в следующем. Предположим, что у нашего класса есть некое событие Clicked, объявленное следующим образом: public event EventHandler Clicked; Если метод генерации события написан в виде: protected void OnUnsafeRaiseClick() { if (Clicked != null ) Clicked( this , EventArgs .Empty); } - это приводит к небезопасному поведению в случае многопоточного исполнения, когда один поток пытается сгенерировать событие, а второй в этот момент отписывает последний делегат. При определенном стечении обстоятельств проверка Clicked != null может пройти успешно (второй поток еще не отписал последний делегат), а попытка выполнить Clicked( this , EventArgs .Empty) может привести к исключению System.NullReferenceException (если второй пот

Текстовый файл в ресурсе сборки

Изображение
На днях спрашивали у меня, как внедрить в сборку текстовый файл и затем прочитать его. Вообще-то задача внедрения и получения текстового файла из сборки по сути аналогична тому, как написано в статье Сергея Розовика Как вытащить иконку из ресурса . Заметил, что эта, в общем-то, несложная задача ставит многих разработчиков в тупик (может быть это потому, что они не читают хороших блогов :-). Поэтому решил описать ее подробнее и для более общего случая. Процесс внедрения может быть описан следующими шагами: Добавляем файл как Embedded Resource. По имени файла в ресурсе получаем поток, позволяющий считать файл. Работаем с потоком, чтобы получить нужный программный объект. Например, строку с содержимым текстового файла или объект изображения/иконки. А теперь более подробно. Для внедрения файла в сборку, надо подключить его к проекту и выставить значение свойства Build Action в Embedded Resource . Теперь после компиляции файл будет внедрен в ресурсы сборки. Переходим к извлечению. Имя файл

Брейкпоинт в другом домене

Изображение
На днях коллега попросил помочь ему разобраться в ситуации. Ситуация достаточно интересная, и поэтому я решил написать о ней в блоге. Мой коллега отлаживал приложение на тестовой машине. Он подключился отладчиком к работающему приложению, подгрузил отладочные символы (pdb -файлы) и поставил брейкпоинт в нужном ему методе. Код, который его интересовал, выглядел приблизительно так: Однако отладчик упорно игнорировал точку прерывания, хотя показывал, что отладочные символы для метода загружены. И я, откровенно говоря, был в замешательстве. Немного поразмыслив, на ум пришел тот факт, что исполнение кода в новом AppDomain приводит к тому, что в него все сборки загружаются отдельно. Отсюда я пришел к гипотезе, что в новый домен не загрузились отладочные символы. Для проверки моего предположения мы скопировали pdb-файл в тот же каталог, откуда загружалась и отлаживаемая сборка. Кстати, узнать путь реальной загрузки сборки можно либо из окна Output (View-> Output), либо окна Modules (Debug

День Программиста

Друзья и коллеги! Сегодня 256-й день года, который традиционно считается Днем Программиста. С чем всех и поздравляю!

Каждый охотник желает знать, где сидит фазан

Эта знакомая с детства фраза – не что иное, как пример мнемонической фразы. Напомню, что мнемоника — это совокупность приемов, имеющих целью облегчить запоминание возможно большего числа сведений, фактов и т.п. путем образования искусственных ассоциаций. Во фразе, которая приведена в заголовке статьи, первая буква каждого слова помогает вспомнить цвет. А сегодня мы поговорим об использовании мнемоники в Visual Studio. В этой среде разработки, как в типичном Windows-приложении, есть два основных способа вызова команд с клавиатуры: горячие клавиши и мнемоника. С горячими клавишами все понятно. В главном меню они высвечиваются справа от текста пункта меню, а для команд панели инструментов высвечиваются во всплывающей подсказке, если установлена соответствующая опция (Tools -> Customize -> Show ScreenTips on toolbars ). Число горячих клавиш ограничено – они назначены только для самых популярных команд. Другой, менее популярный, но более мощный способ быстрого вызова команд, – использ

Техника быстрой локализации ошибок при отладке

Процесс отладки упрощенно состоит из нескольких этапов. Сперва необходимо добиться повторяемости ошибки. Как правило, это делает тот, кто находит и/или регистрирует баг, но в наиболее сложных ситуациях (когда ошибка возникает нерегулярно или ее зависимость от внешних факторов не очевидна) это приходится делать самим. Далее необходимо локализовать баг в программном коде. Чтобы не читать метры кода, лучше максимально сократить тот диапазон, который в дальнейшем придется изучать, чтобы понять, какой фрагмент кода приводит к ошибке. Затем надо понять причину проблемы и, наконец, исправить . По моему опыту, локализация ошибки – наиболее трудоемкий этап в 95% случаев. Если ошибка стала проявляться сравнительно недавно (то есть, можно указать дату и/или номер билда, когда ошибки точно не было и дату и/или номер билда, когда ошибка точно проявляется), могу предложить простую, но эффективную технику, которой сам успешно пользуюсь. Способ локализации ошибки основан на алгоритме двоичного поис

Ловкость рук и никакого мошенничества

Заметил, так же, что многие даже и не подозревают, что если Tab позволяет перемещаться по контролам в прямом порядке: слева на права и сверху в низ, то комбинация Shift + Tab перемещает фокус в обратном направлении. Еще комбинация из разряда особо не известных J . Ctrl + C на стандартных окнах сообщений ( MessageBox ) позволяет скопировать в буфер в текстовом виде содержимое этого окна: заголовок окна, сообщение, надписи на кнопках.

Нетрадиционное использование using и IDisposable

Предположим, что у нас есть форма и на ней кнопка, по нажатию на которую выполняется некая долгоиграющая операция. При выполнении длительных операций в главном потоке приложения, как правило, надо изменить курсор мыши на песочные часы и затем восстановить его. Для этого можно воспользоваться подобным кодом: private void button1_Click( object sender, EventArgs e) { Cursor oldCursor = Cursor .Current; try { Cursor .Current = Cursors .WaitCursor; // do something time consuming DoSomethingTimeConsuming(); } finally { Cursor .Current = oldCursor; } } Хочу обратить внимание, что конструкция try finally необходима, что бы в случае необработанного исключения в DoSomethingTimeConsuming все равно восстановить курсор. Однако у данного обработчика есть несколько недостатков: конструкция достаточно объемна необходимость блока try finally не очевидна и поэтому блок можно забыть. данный код приходится дублировать для каждого подобного обработчика. У меня есть небольшой трюк, который выполняет ту

Установка брейкпоинтов в управляемом коде без исходников

Изображение
Хочу поделиться простой техникой установки точек прерывания (breakpoints) на методах классов, к которым у вас нет исходных кодов. Такой вариант использования брейкпоинтов может понадобиться, если у вас по каким-либо причинам нет исходных текстов компоненты или вас совершенно не интересует исходный код метода, а, скажем, только стек вызова этого метода. Таким образом, данная техника позволяет устанавливать точки прерывания на методах классов NET Framework или третьих фирм. Установка точек прерывания на ключевых методах кода позволяет быстро получить ответ на вопросы типа: почему был вызван некий метод, в какой момент происходит установка свойства, вызывался ли интересующий метод вообще. Такой техникой я обычно пользуюсь, когда нахожусь на стадии локализации проблемы и/или при проверке различных гипотез при отладке. Грамотная установка точек прерывания позволяет быстро узнать стек вызов для интересующего метода, чтобы в итоге понять, откуда у проблемы «ноги растут». Эта техника установки