00001 /* 00002 * CntmLib - Подсчет ссылок, потоки, синхронизация, асинхронные процедуры, события 00003 * Copyright (c) 2005, Овсеевич Роман, CntmLib@mail.ru 00004 * _______________________________________________________________________________ 00005 * Разрешено свободное использование, копирование, распространение, изменение 00006 * (изменение сведений об авторских правах запрещено). Запрещена продажа и 00007 * включение всей библиотеки или ее частей в другие библиотеки. В сведениях об 00008 * авторских правах на программу (или сведениях о программе, об авторах, 00009 * использованных средствах разработки и т.д.) должна быть указана информация 00010 * о библиотеке CntmLib, ее авторе и, возможно, сайте или email'е. 00011 * Библиотека поставляется "как есть", без каких-либо гарантий со стороны автора. 00012 */ 00013 00014 #ifndef CNTM_ASYNCPROC_H 00015 #define CNTM_ASYNCPROC_H 00016 #include <Cntm/Concurrency/ExecutionUnit.h> 00017 #include <Cntm/Synchro/SynchroSpace.h> 00018 #include <Cntm/Synchro/SynchroObject.h> 00019 #include <Cntm/AsyncProc/Internal/ThreadProcFunctor.h> 00020 #include <Cntm/AsyncProc/Internal/DeferProcFunctor.h> 00021 #include <Cntm/AsyncProc/Internal/DirectProcFunctor.h> 00022 #include <Cntm/AsyncProc/AsyncProcTerminatingSignal.h> 00023 #include <Cntm/AsyncProc/BasicAsyncProc.h> 00024 00025 namespace Cntm 00026 { 00027 00028 /** 00029 * Класс асинхронной процедуры. Асинхронная процедура - это такая процедура, завершение 00030 * которой может произойти после начала операции, следующей за вызовом этой процедуры. В 00031 * частности, через асинхронные процедуры можно запускать потоки. 00032 * 00033 * Асинхронная процедура является единицей выполнения и наследует класс Cntm::ExecutionUnit, 00034 * который предоставляет средства для останова единиц выполнения и асинхронных процедур в 00035 * частности. 00036 * 00037 * Создание асинхронной процедуры очень похоже на запуск обычной процедуры. При создании 00038 * указывается объект, его метод, который будет выполнен асинхронно, дополнительные параметры 00039 * и аргументы, которые будут переданы методу при его вызове. Рассмотрим пример создания: 00040 * \code 00041 * AsyncProc::Thread(this, &Class1::AsyncMethod333)("text", 54); 00042 * \endcode 00043 * Метод Thread()() - один из статических методов создания асинхронной процедуры, он будет 00044 * рассмотрен ниже. Выражение AsyncProc::Thread(this, &Class1::AsyncMethod333), по сути, 00045 * является идентификатором асинхронной процедуры, а выражение ("text", 54) означает факт 00046 * запуска асинхронной процедуры. Поэтому метод Thread и ему подобные будут обозначаться так: 00047 * Thread()(). При указании аргументов производится проверка типов указанных значений и типов 00048 * аргументов метода, выполняемого асинхронно. 00049 * 00050 * По способу запуска асинхронные процедуры делятся на запущенные при создании и с 00051 * отсроченным запуском. В первом случае указанный при создании метод будет вызван сразу, 00052 * как только это будет возможно, а во втором - только после явного запуска асинхронной 00053 * процедуры. Методы создания отсроченных процедур имеют префиксы Suspend... . 00054 * 00055 * По способу запуска указанного при создании метода асинхронные процедуры делятся на 00056 * потоковые, отложенные и прямые. Рассмотрим каждый из них. 00057 * 00058 * Потоковые асинхронные процедуры. Создаются статическими методами Thread()() и 00059 * SuspendThread()(). В них создается новый поток, в котором и будет вызван указанный 00060 * метод. При создании потоковой асинхронной процедуры м.б. указан приоритет создаваемого 00061 * потока. Пример: 00062 * \code 00063 * class Class1: public RefBase 00064 * { 00065 * void ThreadMethod1(string s, int e) { ... } // Метод, который будет вызван в другом потоке. 00066 * 00067 * void Start() 00068 * { 00069 * // Вызов метода в новом потоке и передача ему аргументов - числа и строки. 00070 * AsyncProc::Thread(this, &Class1::ThreadMethod1)("text", 54); 00071 * } 00072 * }; 00073 * \endcode 00074 * 00075 * Отложенные асинхронные процедуры. Создаются статическими методами Defer()() и 00076 * SuspendDefer()(). Об отложенном способе вызова подробно рассказывается в документации 00077 * по классу Cntm::DeferEvent, т.к. выполнение отложенной асинхронной процедуры имеет много 00078 * общего с генерацией отложенного события. Вкратце, отложенность процедуры означает, что 00079 * указанный метод будет вызван не в момент запуска, а при выполнении определенных условий. 00080 * Отложенная асинхронная процедура тесно связана с понятием синхропространства 00081 * (ознакомтесь с документацие по классу Cntm::SynchroSpace). Асинхронный метод, указанный 00082 * при создании, выполняется внутри определенного синхропространства (которое тоже 00083 * указывается тем или иным способом при создании асинхронной процедуры), вход в которое 00084 * произведен в реентерабельном режиме. Если запуск процедуры произведен в том 00085 * синхропространстве, которое указано при создании, то гарантируется, что метод будет запущен 00086 * только после выхода из этого синхропространства. При создании отложенной асинхронной 00087 * процедуры требуется указание синхропространства. Если оно не указано явно, то используется 00088 * главное синхропространство. Пример: 00089 * \code 00090 * class Class2: public RefBase 00091 * { 00092 * void DeferMethod1(const string& s, double e) { ... } // Метод, который будет вызван в другом потоке. 00093 * 00094 * void Start() 00095 * { 00096 * // Создание отложенной (defer) отсроченной (suspend) процедуры и передача ей 00097 * // строки и числа, которые будут переданы методу DeferMethod1() при его вызове. 00098 * AsyncProc::SuspendDefer(this, &Class2::DeferMethod1)("text", 54); 00099 * } 00100 * }; 00101 * \endcode 00102 * 00103 * Прямые асинхронные процедуры. Создаются статическими методами Direct()() и 00104 * SuspendDirect()(). По сути представляют вызов указанного при создании метода в момент 00105 * запуска асинхронной процедуры. Прямая процедура, созданная методом Direct()(), вообще 00106 * ничем не отличается от вызова указанного при создании метода, поэтому, ни какого интереса 00107 * не представляет и добавлена только для функциональной полноты. Об использовании метода 00108 * SuspendDirect()(), как и других отсроченных меодов будет рассказано ниже. 00109 * 00110 * Взаимодействие с созданной асинхронной процедурой, как и с единицами выполнения 00111 * (Cntm::ExecutionUnit) вообще, осуществляется через хэндл процедуры (класс 00112 * Cntm::AsyncProcHandle). Хэндл не является шаблонным классом, и никак не зависит от 00113 * сигнатуры указанного при создании асинхронной процедуры метода. Через хэндл можно 00114 * сообщить методу процедуры об останове. Асинхронный метод или методы, им запущенные, 00115 * могут узнать об останове через методы Terminated() и CheckTerminating(), унаследованные 00116 * им от класса Cntm::ExecutionUnit(). Хэндл предоставляет следующие возможности: узнать 00117 * тип процедуры, был ли произведен запуск (для отсроченных процедур, обычные запускаются 00118 * при создании), была ли завершена процедура и если была, то успешно или нет. Также хэндлы 00119 * позволяют запустить отсроченную асинхронную процедуру, дождаться завершения асинхронной 00120 * процедуры, установить отсроченную асинхронную процедуру, которая будет вызвана после 00121 * завершения данной процедуры. 00122 * 00123 * Асинхронный метод может возвращать значение результата. Это значение можно узнать с 00124 * помощью класса результата асинхронной процедуры - Cntm::AsyncProcResult. Данный класс 00125 * является шаблоном, параметром которого является тип возвращаемого значения. Класс 00126 * Cntm::AsyncProcResult наследует Cntm::AsyncProcHandle. Все методы создания асинхронных 00127 * процедур возвращают именно объект результата. Значение результата можно получить только 00128 * после завершения асинхронной процедуры. 00129 * 00130 * По своей сути хэндлы и результаты являются ссылочным указателями на объект асинхронной 00131 * процедуры. Однако отсутствие хэндлов ни как не влияет на выполняющуюся процедуру, но 00132 * если хэндлов, связанных с отсроченной незапущенной процедурой, не осталось, то эта 00133 * процедура уже никогда не сможет быть запущена. Наличие хэндлов, связанных с процедурой, 00134 * влияет только на значение результата асинхронного метода (подробнее об этом - ниже). 00135 * 00136 * Рассмотрим пример асинхронных процедур. 00137 * \code 00138 * class Class3 00139 * { 00140 * string Work() 00141 * { 00142 * sleep(1); 00143 * ... 00144 * return "text"; 00145 * } 00146 * 00147 * void Finish(AsyncProcResult<string> res) 00148 * { 00149 * cout << res << endl; 00150 * } 00151 * 00152 * void Start() 00153 * { 00154 * AsyncProcResult<string> res = AsyncProc::SuspendThread(this, &Class3::Work)(); 00155 * AsyncProctHandle hdl = AsyncProc::SuspendThread(this, &Class3::Finish)(res); 00156 * res.SetFinishProc(hdl); 00157 * cout << "before start" << endl; 00158 * res.Start(); 00159 * hdl.Wait(); 00160 * cout << "after finish" << endl; 00161 * } 00162 * }; 00163 * 00164 * Вывод на консоль: 00165 * before start 00166 * text 00167 * after finish 00168 * \endcode 00169 * 00170 * Разберем пример. В первой строке Start() создается отсроченная потоковая асинхронная 00171 * процедура Work(), выполняющая некоторую работу и возвращающая строку. При создании 00172 * нам возвращается объект результата res, через который мы можем узнать значение, которое 00173 * вернул метод Work(). Во второй строке Start() создается обработчик завершения метода 00174 * Work(), которому передается объект результата метода Work(). В третьей строке происходит 00175 * связывание обработки завершения процедуры Work() с процедурой Finish(). В пятой строке 00176 * происходит запуск процедуры Work(), которая после завершения запустит процедуру Finish(). 00177 * Т.к. Work() закончил работу, то Finish() может получить значение результата (кстати, 00178 * AsyncProcResult имеет оператор преобразования к типу, указанному в шаблоне, поэтому 00179 * выражение cout << res допустимо). В шестой строке производится ожидание завершения этой 00180 * цепочки методов. 00181 * 00182 * Все 12 методов создания асинхронных процедур содержат параметры Object и Method. 00183 * Object - это объект, чей метод Method будет асинхронно вызван. Object может задаваться как 00184 * ссылочный указатель, как обычный указатель или как обычная ссылка, Method задается как 00185 * указатель на метод класса, к которому принадлежит Object. 00186 * 00187 * Дополнительные параметры, указываемые при создании асинхронных процедур. 00188 * При создании потоков методами Thread()() и SuspendThread()() можно указать его приоритет 00189 * (параметр с именем Priority) (см. перечисление Cntm::BasicAsyncProc::ThreadPriority). При 00190 * создании отложенных процедур методами Defer()() и SuspendDefer()() требуется указание 00191 * синхропространства (параметр Space), в котором будет выполняться асинхронный метод. 00192 * Если синхропространство явно не указано, а переданный объект, метод которого будет 00193 * выполнен, является синхрообъектом, то будет использовано синхропространство, к которому 00194 * принадлежит синхрообъект, если передан не синхрообъект, то будет использовано главное 00195 * синхропространство. Последний параметр всех 12 методов (называется HoldRef) имеет значение, 00196 * только если переданный объект - с подсчетом ссылок. Этот параметр влияет на хранение ссылки 00197 * на объект, чей метод будет выполняться. Если параметр устанвлен в true, то на время 00198 * выполнения метода ссылка на объект будет сохранена (это поведение по умолчанию), если в 00199 * false, то нет (это поведение следует использовать с большой осторожностью, т.к. может 00200 * привести к вызову метода несуществующего объекта). 00201 * 00202 * Применение асинхронных процедур. 00203 * 00204 * Потоковые процедуры Thread()() используются для создания потоков с удобной передачей 00205 * аргументов любых типов и возможностью получения результата. Отложенные процедуры 00206 * Defer()() используются для синхронизированного выполнения методов объектов, т.к. 00207 * гарантируют вызов указанного метода внутри синхропространства, например, некий поток 00208 * может синхронизированно вызвать произвольный метод (для главного синхропространства 00209 * это означает, что метод будет вызван в главном цикле обработки сообщений, в главном потоке) 00210 * и либо продолжить работу либо дождаться завершения. Применение отсроченных асинхронных 00211 * процедур. Они создаются методами Suspend...()(). Отсроченные процедуры можно рассматривать 00212 * как объекты, инкапсулирующие вызов метода с уже подготовленными аргументами. Такие 00213 * объекты вызовов можно передавать в качестве параметров (напомним, что любой объект 00214 * вызова характеризуется нешаблонным хэндлом или результатом, зависящим только от типа 00215 * возвращаемого значения), запуская или не запуская инкапсулированные вызовы при 00216 * определенных условиях. Эта методика используется и в самих асинхронных процедурах для 00217 * задания метода, который будет вызван после завершения выполнения асинхронной процедуры. 00218 * В отличии от обычной прямой процедуры отсроченная прямая процедура SuspendDirect()() 00219 * является логичной, полезной и вполне асинхронной. 00220 * 00221 * Особенности. 00222 * 00223 * При создании асинхронной процедуры указываются аргументы, которые впоследствии будут 00224 * переданы асинхронному методу при его вызове. Для этого производится копирование значений 00225 * аргументов во внутренний буфер с помощью конструкторов копирования. Копии аргументов будут 00226 * уничтожены сразу после завершения работы асинхронного метода. Асинхронная процедура хранит 00227 * копию результата, который вернул асинхронный метод. Значение результата создается с помощью 00228 * конструктора копирования после завершения асинхронного метода. Значение результата будет 00229 * уничтожено вместе с уничтожением объекта асинхронной процедуры, т.е. когда не останется ни 00230 * одного хэндла, связанного с процедурой. Если процедура хранит ссылку на объект, то эта 00231 * ссылка будет уничтожена сразу после завершения работы асинхронного метода. Если для 00232 * отсроченной незапущенной процедуры были утеряны все хэндлы, то происходит уничтожение 00233 * объекта процедуры вместе с копиями аргументов и ссылкой на объект (если она имелась). 00234 * 00235 * Принудительный останов асинхронных процедур. Если принудительный останов отсроченной 00236 * процедуры (метод Cntm::AsyncProcHandle::Terminate()) произведен до ее запуска (метод 00237 * Cntm::AsyncProcHandle::Start()), то производится ее завершение (устанавливается флаг 00238 * завершения, запускается обработчик завершения и т.д.), а указанный при создании метод 00239 * объекта никогда вызван не будет. При принудительном останове запущенной процедуры 00240 * гарантируется, что вызов указанного при создании метода объекта будет произведен (конечно, 00241 * если не было ошибок при запуске). 00242 * 00243 * Данный класс обеспечивает многопоточность. 00244 * @author Овсеевич Р. 00245 * \ingroup AsyncProc 00246 */ 00247 class AsyncProc: public ExecutionUnit, public BasicAsyncProc 00248 { 00249 public: 00250 00251 /** 00252 * Создать и запустить асинхронную потоковую процедуру. Создается новый поток и в нем производится запуск метода Method объекта Object. 00253 * 00254 * Формат вызова: Thread(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки. 00255 * 00256 * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult. 00257 * 00258 * Исключения: 00259 * NullArgException - не указан объект обработчик (Object равен NULL). 00260 * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false. 00261 * SystemException - системная ошибка при создании нового потока. 00262 * @param Object - объект-обработчик. Задается обычным указателем. 00263 * @param Method - метод объекта Object, который будет вызван асинхронно в другом потоке. 00264 * @param Priority - приоритет потока, опционально, значение по умолчанию - tpNormal (см. перечисление Cntm::BasicAsyncProc::ThreadPriority). 00265 * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true. 00266 */ 00267 template < typename MethodSignatureT > 00268 static SpecUtils::ThreadProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Thread( 00269 typename SignatureInfo < MethodSignatureT > ::ClassType* Object, 00270 MethodSignatureT Method, 00271 ThreadPriority Priority = tpNormal, 00272 bool HoldRef = true) 00273 { 00274 return SpecUtils::ThreadProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign> 00275 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), Priority, HoldRef, false); 00276 } 00277 00278 /** 00279 * Создать и запустить асинхронную потоковую процедуру. Создается новый поток и в нем производится запуск метода Method объекта Object. 00280 * 00281 * Формат вызова: Thread(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки. 00282 * 00283 * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult. 00284 * 00285 * Исключения: 00286 * NullArgException - не указан объект обработчик (Object равен NULL). 00287 * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false. 00288 * SystemException - системная ошибка при создании нового потока. 00289 * @param Object - объект-обработчик. Задается ссылочным указателем. 00290 * @param Method - метод объекта Object, который будет вызван асинхронно в другом потоке. 00291 * @param Priority - приоритет потока, опционально, значение по умолчанию - tpNormal (см. перечисление Cntm::BasicAsyncProc::ThreadPriority). 00292 * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true. 00293 */ 00294 template < typename MethodSignatureT > 00295 static SpecUtils::ThreadProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Thread( 00296 RefPtr < typename SignatureInfo < MethodSignatureT > ::ClassType > Object, 00297 MethodSignatureT Method, 00298 ThreadPriority Priority = tpNormal, 00299 bool HoldRef = true) 00300 { 00301 return SpecUtils::ThreadProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign> 00302 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), Priority, HoldRef, false); 00303 } 00304 00305 /** 00306 * Создать асинхронную потоковую процедуру без ее запуска. Запуск можно произвести через хэндл или результат. 00307 * 00308 * Формат вызова: SuspendThread(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки. 00309 * 00310 * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult. 00311 * 00312 * Исключения: 00313 * NullArgException - не указан объект обработчик (Object равен NULL). 00314 * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false. 00315 * @param Object - объект-обработчик. Задается обычным указателем. 00316 * @param Method - метод объекта Object, который будет вызван асинхронно в другом потоке. 00317 * @param Priority - приоритет потока, опционально, значение по умолчанию - tpNormal (см. перечисление Cntm::BasicAsyncProc::ThreadPriority). 00318 * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true. 00319 */ 00320 template < typename MethodSignatureT > 00321 static SpecUtils::ThreadProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > SuspendThread( 00322 typename SignatureInfo < MethodSignatureT > ::ClassType* Object, 00323 MethodSignatureT Method, 00324 ThreadPriority Priority = tpNormal, 00325 bool HoldRef = true) 00326 { 00327 return SpecUtils::ThreadProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign> 00328 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), Priority, HoldRef, true); 00329 } 00330 00331 /** 00332 * Создать асинхронную потоковую процедуру без ее запуска. Запуск можно произвести через хэндл или результат. 00333 * 00334 * Формат вызова: SuspendThread(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки. 00335 * 00336 * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult. 00337 * 00338 * Исключения: 00339 * NullArgException - не указан объект обработчик (Object равен NULL). 00340 * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false. 00341 * @param Object - объект-обработчик. Задается ссылочным указателем. 00342 * @param Method - метод объекта Object, который будет вызван асинхронно в другом потоке. 00343 * @param Priority - приоритет потока, опционально, значение по умолчанию - tpNormal (см. перечисление Cntm::BasicAsyncProc::ThreadPriority). 00344 * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true. 00345 */ 00346 template < typename MethodSignatureT > 00347 static SpecUtils::ThreadProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > SuspendThread( 00348 RefPtr < typename SignatureInfo < MethodSignatureT > ::ClassType > Object, 00349 MethodSignatureT Method, 00350 ThreadPriority Priority = tpNormal, 00351 bool HoldRef = true) 00352 { 00353 return SpecUtils::ThreadProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign> 00354 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), Priority, HoldRef, true); 00355 } 00356 00357 /** 00358 * Создать и запустить асинхронную отложенную процедуру. Производит синхронизированный запуск метода Method объекта Object в указанном синхропространстве Space. Если объект Object является синхрообъектом и синхропространство явно не указано, то используется синхропространство, к которому принадлежит синхрообъект (свойство Cntm::SynchroObject::Space()). Если объект Object не является синхрообъектом и синхропространство явно не указано, то используется главное синхропространство. 00359 * 00360 * Формат вызова: Defer(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки. 00361 * 00362 * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult. 00363 * 00364 * Исключения: 00365 * NullArgException - не указан объект обработчик (Object равен NULL). 00366 * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false. 00367 * IllegalStateException - если синхропространство не указано явно, объект не является синхрообъектом и не создано главное синхропространство. 00368 * @param Object - объект-обработчик. Задается обычным указателем. 00369 * @param Method - метод объекта Object, который будет вызван синхронизированно в указанном синхропространстве. 00370 * @param Space - синхропространство, в котором будет выполнен метод. Если явно не указано, тоиспользуется синхропространство объекта Object, если это синхрообъект, иначе используется главное синхропространство. 00371 * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true. 00372 */ 00373 template < typename MethodSignatureT > 00374 static SpecUtils::DeferProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Defer( 00375 typename SignatureInfo < MethodSignatureT > ::ClassType* Object, 00376 MethodSignatureT Method, 00377 SynchroSpace::Ptr Space = SynchroSpace::Ptr(), 00378 bool HoldRef = true) 00379 { 00380 return SpecUtils::DeferProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign> 00381 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), GetSpace(Object, Space), HoldRef, false); 00382 } 00383 00384 /** 00385 * Создать и запустить асинхронную отложенную процедуру. Производит синхронизированный запуск метода Method объекта Object в указанном синхропространстве Space. Если объект Object является синхрообъектом и синхропространство явно не указано, то используется синхропространство, к которому принадлежит синхрообъект (свойство Cntm::SynchroObject::Space()). Если объект Object не является синхрообъектом и синхропространство явно не указано, то используется главное синхропространство. 00386 * 00387 * Формат вызова: Defer(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки. 00388 * 00389 * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult. 00390 * 00391 * Исключения: 00392 * NullArgException - не указан объект обработчик (Object равен NULL). 00393 * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false. 00394 * IllegalStateException - если синхропространство не указано явно, объект не является синхрообъектом и не создано главное синхропространство. 00395 * @param Object - объект-обработчик. Задается ссылочным указателем. 00396 * @param Method - метод объекта Object, который будет вызван синхронизированно в указанном синхропространстве. 00397 * @param Space - синхропространство, в котором будет выполнен метод. Если явно не указано, тоиспользуется синхропространство объекта Object, если это синхрообъект, иначе используется главное синхропространство. 00398 * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true. 00399 */ 00400 template < typename MethodSignatureT > 00401 static SpecUtils::DeferProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Defer( 00402 RefPtr < typename SignatureInfo < MethodSignatureT > ::ClassType > Object, 00403 MethodSignatureT Method, 00404 SynchroSpace::Ptr Space = SynchroSpace::Ptr(), 00405 bool HoldRef = true) 00406 { 00407 return SpecUtils::DeferProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign> 00408 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), GetSpace(Object.Pointer(), Space), HoldRef, false); 00409 } 00410 00411 /** 00412 * Создать асинхронную отсроченную отложенную процедуру. Когда процедура будет запущена, то метод Method объекта Object будет синхронизированно вызван в указанном синхропространстве Space. Если объект Object является синхрообъектом и синхропространство явно не указано, то используется синхропространство, к которому принадлежит синхрообъект (свойство Cntm::SynchroObject::Space()). Если объект Object не является синхрообъектом и синхропространство явно не указано, то используется главное синхропространство. 00413 * 00414 * Формат вызова: SuspendDefer(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки. 00415 * 00416 * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult. 00417 * 00418 * Исключения: 00419 * NullArgException - не указан объект обработчик (Object равен NULL). 00420 * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false. 00421 * IllegalStateException - если синхропространство не указано явно, объект не является синхрообъектом и не создано главное синхропространство. 00422 * @param Object - объект-обработчик. Задается обычным указателем. 00423 * @param Method - метод объекта Object, который будет вызван синхронизированно в указанном синхропространстве. 00424 * @param Space - синхропространство, в котором будет выполнен метод. Если явно не указано, тоиспользуется синхропространство объекта Object, если это синхрообъект, иначе используется главное синхропространство. 00425 * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true. 00426 */ 00427 template < typename MethodSignatureT > 00428 static SpecUtils::DeferProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > SuspendDefer( 00429 typename SignatureInfo < MethodSignatureT > ::ClassType* Object, 00430 MethodSignatureT Method, 00431 SynchroSpace::Ptr Space = SynchroSpace::Ptr(), 00432 bool HoldRef = true) 00433 { 00434 return SpecUtils::DeferProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign> 00435 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), GetSpace(Object, Space), HoldRef, true); 00436 } 00437 00438 /** 00439 * Создать асинхронную отсроченную отложенную процедуру. Когда процедура будет запущена, то метод Method объекта Object будет синхронизированно вызван в указанном синхропространстве Space. Если объект Object является синхрообъектом и синхропространство явно не указано, то используется синхропространство, к которому принадлежит синхрообъект (свойство Cntm::SynchroObject::Space()). Если объект Object не является синхрообъектом и синхропространство явно не указано, то используется главное синхропространство. 00440 * 00441 * Формат вызова: SuspendDefer(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки. 00442 * 00443 * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult. 00444 * 00445 * Исключения: 00446 * NullArgException - не указан объект обработчик (Object равен NULL). 00447 * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false. 00448 * IllegalStateException - если синхропространство не указано явно, объект не является синхрообъектом и не создано главное синхропространство. 00449 * @param Object - объект-обработчик. Задается ссылочным указателем. 00450 * @param Method - метод объекта Object, который будет вызван синхронизированно в указанном синхропространстве. 00451 * @param Space - синхропространство, в котором будет выполнен метод. Если явно не указано, тоиспользуется синхропространство объекта Object, если это синхрообъект, иначе используется главное синхропространство. 00452 * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true. 00453 */ 00454 template < typename MethodSignatureT > 00455 static SpecUtils::DeferProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > SuspendDefer( 00456 RefPtr < typename SignatureInfo < MethodSignatureT > ::ClassType > Object, 00457 MethodSignatureT Method, 00458 SynchroSpace::Ptr Space = SynchroSpace::Ptr(), 00459 bool HoldRef = true) 00460 { 00461 return SpecUtils::DeferProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign> 00462 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), GetSpace(Object.Pointer(), Space), HoldRef, true); 00463 } 00464 00465 /** 00466 * Создать и запустить прямую процедуру. По сути, ни чем не отличается от обычного запуска метода Method объекта Object. 00467 * 00468 * Формат вызова: Direct(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки. 00469 * 00470 * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult. 00471 * 00472 * Исключения: 00473 * NullArgException - не указан объект обработчик (Object равен NULL). 00474 * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false. 00475 * @param Object - объект-обработчик. Задается обычным указателем. 00476 * @param Method - метод объекта Object, который будет вызван при создании процедуры. 00477 * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true. 00478 */ 00479 template < typename MethodSignatureT > 00480 static SpecUtils::DirectProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Direct( 00481 typename SignatureInfo < MethodSignatureT > ::ClassType* Object, 00482 MethodSignatureT Method, 00483 bool HoldRef = true) 00484 { 00485 return SpecUtils::DirectProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign> 00486 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), HoldRef, false); 00487 } 00488 00489 /** 00490 * Создать и запустить прямую процедуру. По сути, ни чем не отличается от обычного запуска метода Method объекта Object. 00491 * 00492 * Формат вызова: Direct(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки. 00493 * 00494 * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult. 00495 * 00496 * Исключения: 00497 * NullArgException - не указан объект обработчик (Object равен NULL). 00498 * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false. 00499 * @param Object - объект-обработчик. Задается ссылочным указателем. 00500 * @param Method - метод объекта Object, который будет вызван при создании процедуры. 00501 * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true. 00502 */ 00503 template < typename MethodSignatureT > 00504 static SpecUtils::DirectProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Direct( 00505 RefPtr < typename SignatureInfo < MethodSignatureT > ::ClassType > Object, 00506 MethodSignatureT Method, 00507 bool HoldRef = true) 00508 { 00509 return SpecUtils::DirectProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign> 00510 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), HoldRef, false); 00511 } 00512 00513 /** 00514 * Создать прямую процедуру. Подготавливает вызов метода Method объекта Object. 00515 * 00516 * Формат вызова: SuspendDirect(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки. 00517 * 00518 * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult. 00519 * 00520 * Исключения: 00521 * NullArgException - не указан объект обработчик (Object равен NULL). 00522 * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false. 00523 * @param Object - объект-обработчик. Задается обычным указателем. 00524 * @param Method - метод объекта Object, который будет вызван при создании процедуры. 00525 * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true. 00526 */ 00527 template < typename MethodSignatureT > 00528 static SpecUtils::DirectProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > SuspendDirect( 00529 typename SignatureInfo < MethodSignatureT > ::ClassType* Object, 00530 MethodSignatureT Method, 00531 bool HoldRef = true) 00532 { 00533 return SpecUtils::DirectProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign> 00534 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), HoldRef, true); 00535 } 00536 00537 /** 00538 * Создать прямую процедуру. Подготавливает вызов метода Method объекта Object. 00539 * 00540 * Формат вызова: SuspendDirect(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки. 00541 * 00542 * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult. 00543 * 00544 * Исключения: 00545 * NullArgException - не указан объект обработчик (Object равен NULL). 00546 * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false. 00547 * @param Object - объект-обработчик. Задается ссылочным указателем. 00548 * @param Method - метод объекта Object, который будет вызван при создании процедуры. 00549 * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true. 00550 */ 00551 template < typename MethodSignatureT > 00552 static SpecUtils::DirectProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > SuspendDirect( 00553 RefPtr < typename SignatureInfo < MethodSignatureT > ::ClassType > Object, 00554 MethodSignatureT Method, 00555 bool HoldRef = true) 00556 { 00557 return SpecUtils::DirectProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign> 00558 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), HoldRef, true); 00559 } 00560 00561 private: 00562 00563 /** 00564 * Определить синхропространство для отложенных процедур. Метод для случая, когда указан синхрообъект. Если синхропространство указано явно, то используется оно, иначе используется синхропространство объекта. 00565 */ 00566 static SynchroSpace::Ptr GetSpace(const IBasicSynchro* Object, const SynchroSpace::Ptr Space) 00567 { 00568 return (!Space && Object)? Object->Space() : Space; 00569 } 00570 00571 /** 00572 * Определить синхропространство для отложенных процедур. Метод для случая, когда указан не синхрообъект. Если синхропространство указано явно, то используется оно, иначе используется главное синхропространство. 00573 */ 00574 static SynchroSpace::Ptr GetSpace(const void* Object, const SynchroSpace::Ptr Space) 00575 { 00576 return Space; 00577 } 00578 }; 00579 00580 } 00581 00582 #endif //CNTM_ASYNCPROC_H
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой 1.5.3 |