Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Hello, World!
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  10:16[Войти] | [Зарегистрироваться]

Обсуждение материала
Работа с потоками в Delphi: так ли страшен чёрт, как его малюют?
Полный текст материала


Другие публикации автора: Юрий Балыкин

Цитата или краткий комментарий:

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


Важно:
  • Страница предназначена для обсуждения материала, его содержания, полезности, соответствия действительности и так далее. Смысл не в разборке, а в приближении к истине :о) и пользе для всех.
  • Любые другие сообщения или вопросы, а так же личные эмоции в адрес авторов и полемика, не относящаяся к теме обсуждаемого материала, будут удаляться без предупреждения авторов, дабы не мешать жителям нормально общаться.
  • При голосовании учитывайте уровень, на который расчитан материал. "Интересность и полезность" имеет смысл оценивать относительно того, кому именно предназначался материал.
  • Размер одного сообщений не должен превышать 5К. Если Вам нужно сказать больше, сделайте это за два раза. Или, что в данной ситуации правильнее, напишите свою статью.
Всегда легче осудить сделанное, нежели сделать самому. Поэтому, пожалуйста, соблюдайте правила Королевства и уважайте друг друга.



Добавить свое мнение.

Результаты голосования
Оценка содержания

  Содержит полезные и(или) интересные сведения
[1]2083.3%
 
  Ничего особенно нового и интересного
[2]416.7%
 
  Написано неверно (обязательно укажите почему)
[3]00%
 
Всего проголосовали: 24

Оценка стиля изложения

  Все понятно, материал читается легко
[1]23100%
 
  Есть неясности в изложении
[2]00%
 
  Непонятно написано, трудно читается
[3]00%
 
Всего проголосовали: 23




Смотрите также материалы по темам:
[TThread] [Потоки (нити) Threads]

Комментарии жителей
Отслеживать это обсуждение

Всего сообщений: 48

18-11-2009 14:34
Сорри, сайт не понимает тег url=..., а редактировать мессаги нельзя.

Вот правильные ссылки кому интересно:

Exe - http://rapidshare.com/files/308902774/ResPulling.rar

Исходники - http://rapidshare.com/files/308902775/ResPullingSource.rar


18-11-2009 14:19
Спасибо за статью и за комментарии!

Прочитав, поэкспериментировал с потоками, вот что получилось:

Программа">http://rapidshare.com/files/308902774/ResPulling.rar]Программа перетягивания одного ресурса двумя потоками:)

З.Ы.: исходники здесь.">http://rapidshare.com/files/308902775/ResPullingSource.rar]здесь.



02-07-2009 02:42
В качестве аналогии можно автотранспорт привести:
Пусть у нас есть две дороги, по которым движутся автомобили (это наши потоки). В одном месте они пересекаются. Перекресток это и есть наш объект. Пока машин мало, они могут проезжать через перекресток друг другу не мешая. Но когда их станет больше, обязательно найдутся две, которые захотят проехать через перекресток одновременно и столкнутся. В этот момент может произойти порча данных и прочие неприятности. Чтобы столкновения не происходили, на перекрестках ставят средства синхронизации - семафоры или регулировщиков.


01-07-2009 11:45
>>> Поток, сгенерировавший событие, приостанавливается
Вам лучше задать этот вопрос не в обсуждении, а как отдельный вопрос. Потому что вот так, вкратце, задача не понятна. Понятно, что вызывающий поток остановится, но чего вы хотите достичь, используя "таймер" в потоке мне совершенно непонятно.


01-07-2009 08:44
Под передачей потоку управления ничего путевого я не подразумевал. Не разобрался просто, в том числе и с терминологией. Но с вашей помощью дела идут в гору.


01-07-2009 02:08
А передать управление потоку можно, в том числе, вызвав метод того самого объекта. Что вы понимаете под "передать управление потоку"?
Если Вы из основного потока вызовите метод объекта созданного в потоке, то этот метод будет выполняться в основном потоке, что может привести (а может не привести) к ошибке. Надо стремиться свести к минимуму взаимодействие потоков, т.е. всё, что создано внутри потока в нём же и используется и уничтожается, а всё остальное для него не существует. Что делать, когда всё-таки приходится организовывать взаимодействие, довольно подробно описано.
 Cep


01-07-2009 02:04
Есть очень интересная библиотека - OmniThreadLibrary http://code.google.com/p/omnithreadlibrary/
Исходники лучше забирать из SVN.


01-07-2009 00:43
"...метод не может быть привязан ни к одной нити". Вот. Поэтому я и говорю о недопонимании с моей стороны. Я-то как понимаю: если в потоке у меня создан некий объект, то все функционирование этого объекта идет только тогда, когда этому потоку передается управление. А передать управление потоку можно, в том числе, вызвав метод того самого объекта. Ошибся, видимо. А сколько таких ошибок еще будет? Поэтому и прошу статью :)


01-07-2009 00:35
Я написал "...событие, к которому привязана процедура..." Конечно же, привязан метод.

А какая разница? Принципиальное отличие метода от процедуры только одно: у метода существует неявный параметр Self. И метод, как и процедура, не может быть привязан ни к одной нити.


01-07-2009 00:16
К момему предыдущему сообщению. Я написал "...событие, к которому привязана процедура..." Конечно же, привязан метод. Извините, что не в тему, но может быть кто-нибудь напишет статью на тему навроде: "организация системы сбора данных с реализацией опроса порта и вычислений в разных потоках"? Судя по всему, это - классическая задача, а приходится перелопачивать тонны макулатуры (извиняюсь за точное выражение) в поисках ее реализации.


30-06-2009 23:53
Вот что осталось (среди прочего) не понятым: если в потоке в процедуре Execute генерируется некое событие (к примеру, TNotifyEvent), к которому привязана процедура из другого потока

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

А набегание ошибки таймера неизбежно всегда, таймер в Windows - очень неточный инструмент.


30-06-2009 08:24
Вот что осталось (среди прочего) не понятым: если в потоке в процедуре Execute генерируется некое событие (к примеру, TNotifyEvent), к которому привязана процедура из другого потока, то что происходит при генерации события? Поток, сгенерировавший событие, приостанавливается, управление передается потоку-обработчику события и т.д. и т.п.? А если в одном потоке у меня таймер, в другом: опрос порта и вычисления по тику таймера, тогда как быть?... "Набегание" ошибки таймера неизбежно?


06-05-2009 02:10
Спасибо большое.
Про "умножение сущностей" написано зря, с таких статей начинать изучение в 100 раз эффективнее, нежели просто куря справки/хелпы/мануалы.
 Efes


05-02-2009 02:37
Мне тоже статья понравилось, спасибо! :))


04-02-2009 05:04
Большое спасибо, побольше бы таких простых и понятных статей


17-09-2008 13:03
Есть идеи завести паблик-свойство отражающее процент расчета
Идея правильная.
а также добавить событие когда это значение именяется.
А вот это уже ни к чему. Пользователю совершенно необязательно знать о том, что в данную милисекунду выполнено ровно 33% работы, а вызов события (да ещё и через Synchronize) может (иногда существенно) замедлить сам расчёт. Я же считаю, что расчёт приоритетен, а проценты это так, для особо нетерпеливых, поэтому обновляю прогресс по таймеру, например раз в секунду (можно и реже, зависит от задачи). Это кстати упрощает и расчёт "оставшегося времени", которое часто показывается вместе с прогрессом, и изменение "паблик-свойства", потому что не надо вызывать метод, достаточно изменить поле, а делать это можно сколь угодно часто не боясь затормозить алгоритм.
 DRON


17-09-2008 04:38
Пока писал пришло в голову использовать сообщения ))) Гоните дурные мысли. Можно и сообщения, но зачем городить огород? Если в событии TNotifyEvent стандартно указывается Sender (чтобы узнать у кого конеретно оно произошло), кроме того после набора кода

Thread1.  // Вываливается список свойств и событий

легко догадаться что нужно сделать. А при использовании сообщений Windows надо это еще както доходчиво задокументировать, разжевать будущим пользователям.
 Cep


17-09-2008 03:56
В дополнение:
Вопрос "правильной" практической реализации, который давно меня мучает. Скажем есть сложный математический расчет с кучей циклов, разветвлений и т.д. Он, понятное дело, оформлен отдельным классом в отдельном модуле. Как сделать для такого варианта что-то наподобие прогрессбара? Есть идеи завести паблик-свойство отражающее процент расчета, а также добавить событие когда это значение именяется. Из программы запустить расчет в отдельном потоке, а в событии изменения процента расчета использовать синхронизацию. Пока писал пришло в голову использовать сообщения )))


15-09-2008 22:27
Просто понятно. Спасибо.


29-07-2008 17:25
Статья для новичков, безусловно, понятная. А осмелев и поэкспериментировав с десятком разных примеров, можно уже переходить и к более продвинутому уровню.

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

Итак, имеются 2 модуля - главный и потока.

В главном модуле:


WordApp:=TWordApplication.Create(NIL); //переменная в этом же модуле
WordApp.ConnectKind:=ckNewInstance;
WordDoc:=TWordDocument.Create(NIL); //тоже
...
загрузка в Word документа в режиме редактирования
...
вызов потока MyThread
...
ПОПЫТКА ПРОДОЛЖИТЬ РАБОТУ С ЗАГРУЖЕННЫМ ДОКУМЕНТОМ



В модуле потока метод Execute:


CoInitializeEx(NIL,COINIT_APARTMENTTHREADED); //=CoInitialize(NIL);
WordApp:=TWordApplication.Create(NIL); //локальная переменная модуля потока
WordApp.ConnectKind:=ckNewInstance;
WordDoc:=TWordDocument.Create(NIL); //тоже
...
загрузка в Word документа в режиме редактирования, но без фактического редактирования - просто получение статистики
...
WordApp.Disconnect; //WordApp.Quit вызывать нельзя, тк сервер Word один на все потоки, это выяснилось при экспериментировании
WordDoc.Free;
WordApp.Free;
CoUninitialize;



И вот. При попытке продолжить работу с документом - ошибка - не дает работать с регионами (Range), внесенными в массив до вызова потока. В чем может быть причина? Поток, он вообще загружает/выгружает не один документ, а все, находящиеся в нужной папке. Я не настаиваю, но, вроде, ошибка сохраняется, даже если в потоке загрузить другой документ Word


26-07-2008 11:16
Прочитал и сразу захотелось написать что нибудь многопоточное! :)

IMHO очень мало информации по обмену данными между потоком и приложением.
>>>... например работа с сокетами, COM-портом ...
подразумевает получение потоком определенного обьема данных и просто посылкой сообщения тут не обойтись.
>>>Общение потока с программой может быть реализовано огромным количеством способов - выбирайте любой, в основном я пользуюсь сообщениями. (C) Python, обсуждение "Создаем дружественный интерфейс"
Т.к. статья "Hello, World!" думаю в ней будет уместно упомянуть и о других безопасных способах передачи данных. Хотя бы для "правильной ориентации" читателя в нужном направлении.
 Ivax


24-07-2008 06:19
http://dn.codegear.com/article/28258


22-07-2008 12:04
Да, Queue работает так же, как и Synchronize, только не ждёт завершения работы метода. Т.е. ставит метод в очередь и сразу же выходит.


22-07-2008 11:11
сообщение от автора материала
А в некоторых, помимо него, есть ещё и метод Queue.
Если не ошибаюсь, Queue не останавливает выполнение потока?
В Delphi7 точно этого нет. В других версиях, увы, работать не приходилось.


22-07-2008 06:42
>>> рекомендация (совет) по теме Synchronize(). Его можно использовать из дополнительного потока не создавая лишних объектов TThread и лишних статических методов
Не во всякой Delphi есть статический Synchronize.
А в некоторых, помимо него, есть ещё и метод Queue.


22-07-2008 06:22
Полезная статья. Сам с потоками работал мало, теперь же вижу явные ошибки в своих многотпотоковых программах.


19-07-2008 00:55
сообщение от автора материала
2 Дмитрий
За замечания спасибо.
Что в статье особенного, нового? - абсолютно ничего. Эта статья для начинающих, только основы и всё.
По поводу остальных замечаний: я думаю написать продолжение, где всё это более подробно разобрать на примере конкретного приложения. Ведь кроме Ваших замечаний много неясностей остаётся - как объекты создавать, как с ними работать, как данными между потоками обмениваться и т.д.
у Рихтера классно разжеван материал, касаемый реализации многопоточности в Windows. Советую его почитать.
Вот как раз после его прочтения у меня и появилась мысль статью написать :)


18-07-2008 16:32
2 Дмитрий:

Все-таки Вы неоправданно строги к автору. Объем информации для HelloWorld вполне достаточен (с анализ флага Terminated согл.), а лаконичность и понятность - одно из главных достоинств. То, что надо, для начала работы. А в обсуждении много чего есть в развитие темы.

За замечания - респект, очень ценно.


18-07-2008 15:29
Что в статье особенного, нового? Подобного материала в интернете весьма много, изложенного не менее подробно. Начинающий программист наверно оценит (часть ДО критических секций изложена неплохо), но тут в целом изложен самый минимум (вроде материал есть, но для практических дел его явно маловато).
Мои замечания и рекомендации:
- Реально работающие параллельно потоки могут быть только на машинах с двумя и более процессорами.
про многоядерные процессоры тоже забывать не стоит. В них реальная параллельность.

- В однопоточном приложении Sleep используется редко, а вот в потоках его использовать очень удобно. Пример - бесконечный цикл, пока не выполнится какое-нибудь условие. Если не вставить туда Sleep мы будем просто нагружать систему бесполезной работой.
удобнее использовать объекты ядра Windows - Events, а Sleep() заменить на WaitFor[SingleObject]. Тем самым появляется дополнительное преимущество - возможность в любой момент прервать ожидание путем вызова SetEvent() из основного потока.

- не раскрыта тема завершения работы потока по анализу флага Terminated, а это - один из главных пунктов.

- рекомендация (совет) по теме Synchronize(). Его можно использовать из дополнительного потока не создавая лишних объектов TThread и лишних статических методов. Такой прием весьма удобен:

TThread.Synchronize(nil, Form1.Show);
TThread.Synchronize(nil, Form1.Hide);
TThread.Synchronize(nil, Form1.Close);
TThread.Synchronize(nil, Form1.Free);

- Самый интересный способ, на мой взгляд — критические секции. Работают они следующим образом: внутри критической секции может работать только один поток, другие ждут его завершения.

завершение кого? потока? или блокировки крит. секции? Рекомендую более качественно изучить тему критических секций и исправить формулировку.

- есть еще события (TEvent), а так же объекты системы, такие как мьютексы (Mutex), семафоры (Semaphore), но они больше подходят для взаимодействия между приложениями.

Событий TEvent нет. В Windows они по-другому называются. Другое дело, в модуле SyncObjs есть класс-обертка TEvent. Кстати Эвенты используются чаще для синхронизации именно между потоками одного процесса (работу с СОМ-портом, например, по-другому не построишь). Тема объектов синхронизации подробно раскрыта в MSDN.

- у Рихтера классно разжеван материал, касаемый реализации многопоточности в Windows. Советую его почитать. Очень много нового можно для себя почерпнуть.


18-07-2008 02:30
2Ins, ваше замечание о приоритетах некорректно. Оно следует из чтения документации, но в жизни все не так.
Посмотрите на dtf.ru статью о многозадачности Windows.

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


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

Кстати, приведенное Вами утверждение, по меньшей мере странное. Обоснуйте его, так как непонятно совсем, зачем "самостоятельно предусматривать слипы" в потоках с равными приоритетами для уравнивания между ними шансов на получение кванта? Неужели Вы считаете, что система не передаст управление другому потоку с таким же приоритетом по истечению кванта первого?
 Ins


18-07-2008 00:58
2Ins, ваше замечание о приоритетах некорректно. Оно следует из чтения документации, но в жизни все не так.
Посмотрите на dtf.ru статью о многозадачности Windows.

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


16-07-2008 03:49
По моему мнению эта статья просто вольный перевод справки. Не умножайте сущности сверх необходимого
Точно установлено, что восприятие текста на родном языке происходит быстрее даже у того, кто очень хорошо владеет иностранным. А если его знаешь плохо, то приходится изучать два языка сразу - программирования и английский. Так что подобные статьи служат для облегчения этого процесса, причем когда они дополнены примерами, описаниями "подводных камней" - они гораздо полезнее справки. А help он всегда под рукой, в нужный момент можно и туда обратиться.


16-07-2008 03:43
>>> Выход из критической секции должен быть выполнен в любом случае, если этого не сделать, ваше приложение намертво повиснет при следующей попытке входа в критическую секцию.
Кстати, оно намертво повиснет и в противном случае: если выйти больше раз, чем зашли.

Например:

CS.Enter;
try
  if WorldCollapseHappens then
  begin
    CS.Leave; // некоторые считают (неверно), что при Exit блок finally не выполнится => двойное освобождение
    Exit;
  end;
finally
  CS.Leave;
end;

...

CS.Enter; // <= deadlock

P.S. На Vista поведение критических секций изменено и там такого нет.


16-07-2008 03:29
сообщение от автора материала
Обрамлять их секцией try..finally..end - жизнено необходимо!
Вот это забыл упомянуть, каюсь. Следующий раз буду внимательней :)  
И про приоритеты наверное стоило подробней расписать.


16-07-2008 03:11
Про приоритеты и то, как их выбирать, я бы описал подробнее.

Ставить высокие приоритеты потокам не стоит, если этого не требует задача, так как это сильно нагружает систему.

Я бы сказал так:
1. Если ваш поток выполняется достаточно продолжительные действия, которые необходимо выполнять, так сказать в фоновом режиме, то такому потоку лучше выставить приоритет пониже. Так как в противном случае, он будет забирать у других потоков много процессорного времени, что скажется на общей производительности. Если же его приоритет будет низким, то фоновые действия будут выполняться только тогда, когда системе больше нечем заняться более важным.
2. Если ваш поток выполняет непродолжительные действия, однако требует от системы максимальной отзывчивости, т.е. эти действия нужно выполнять сразу при определенном условии и как можно быстрее, то потоку имеет смысл поставить приоритет повыше. Так как в противном случае, поток сможет выполнить свои действия только тогда, когда в системе не будет других задач, как большой, так и средней важности. Если же приоритет поставить высокий, то поток немедленно вытеснит все задачи с меньшим приоритетом и выполнит свои действия. А так как время их выполнения невелико, то на производительности системы это не скажется отрицательно - поток пробудился, забрал на себя процессорное время, быстро выполнил свои действия и вернул ресурс системе.

И по поводу критических секций небольшое замечание... Обрамлять их секцией try..finally..end - жизнено необходимо! :) И это даже важнее, чем обрамлять таким же образом Create/Free объектов. Выход из критической секции должен быть выполнен в любом случае, если этого не сделать, ваше приложение намертво повиснет при следующей попытке входа в критическую секцию.
 Ins


16-07-2008 02:22
По моему мнению эта статья просто вольный перевод справки. Не умножайте сущности сверх необходимого.


15-07-2008 16:06
сообщение от автора материала
Хорошо бы укоротить строки в коде, а то приходится двигать текст по горизонтали.
Там просто одна строка должна за пределами кода быть, а попала в код.

толстый намёк на необходимость продолжения :)
Спасибо, будем стараться :)


15-07-2008 15:17
Хорошо бы укоротить строки в коде, а то приходится двигать текст по горизонтали.
Статья безусловно полезная, но всё-таки мало внимания уделено опасностям которые подстерегают программиста многостаночника :)
Было бы не плохо упомянуть, что при использовании TBitmap в потоке надо обязательно использовать Lock/Unlock

var B: TBitmap;
begin
  ...
  B.Canvas.Lock;
  // Здесь что-то рисуем
  B.Canvas.Unlock;

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


15-07-2008 11:05
>>> Даа, там целая книга. Спасибо за ссылку, полезный материал.
Жаль только, что перевели частично, да и забросили вроде (2005-го года обновление).


15-07-2008 10:30
сообщение от автора материала
Пожалуй, исчерпывающий (но и объёмный) материал о потоках: http://forum.vingrad.ru/forum/topic-60076.html
Даа, там целая книга. Спасибо за ссылку, полезный материал.


15-07-2008 10:25
сообщение от автора материала
а чем использование объекта TThread лучше API винды?
Вы имеете ввиду CreateThread/BeginThread? Собственно, TThread есть просто "обёртка" над этими функциями, ведь в любом случае новый поток создаёт ОС, без их вызова не обойтись. Просто с ним удобней работать.


15-07-2008 10:25
TMultiReadExclusiveWriteSynchronizer спасет отца русской демократии... :)


15-07-2008 10:24
Пардон. Я всегда использую Windows.TRtlCriticalSection, даже не могу точно сказать, почему :) Видимо, в примере, по которому я учился, было так.

Пожалуй, исчерпывающий (но и объёмный) материал о потоках: http://forum.vingrad.ru/forum/topic-60076.html


15-07-2008 10:18
>>> а чем использование объекта TThread лучше API винды?
Удобством. Примерно тем же, чем TFileStream "лучше" CreateFile/ReadFile и т.п.


15-07-2008 10:07
а чем использование объекта TThread лучше API винды?


15-07-2008 10:03
Пользительно. Сам до этого докапывался, а тут всё и сразу. Критические секции вообще не использовал, теперь буду. Спасибо за статью.


15-07-2008 09:10
сообщение от автора материала
Спасибо за комментарий, принимаю Ваши замечания, за исключением последнего: в SyncObjs объявлено описание TCriticalSection, поэтому и упомянул.


15-07-2008 08:24
Мелкие замечания:
1. Параллельность - на компьютерах с несколькими процессорами и/или многоядерном процессоре.
2. Resume - не запуск, а пробуждение спящего потока.
3. Неясно, к чему упомянут SyncObjs.

Думаю, начинающим для первого ознакомления вполне подойдёт ;-)


Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
"Мы с тобой одной крови — ты и я!". Чьи это заветные слова?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.

Оценка содержания
 
Содержит полезные и(или) интересные сведения
 
Ничего особенно нового и интересного
 
Написано неверно (обязательно укажите почему)


Оценка стиля изложения
 
Все понятно, материал читается легко
 
Есть неясности в изложении
 
Непонятно написано, трудно читается

Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования