Mutex.ExecuteFunctionInSeparateThread

From SunFlurry wiki
Jump to: navigation, search
  ExecuteFunctionInSeparateThread (Работа с подчиненными потоками)
Объект:Семафор
Статус разработки: Реализована
Тип:Функция
Обращение к БД:Нет
Исключения:Невозможно превратить в строку, число, неверные параметры вызова, системная ошибка
Визуальность:Нет

Функция инициирует исполнение функции с указанным именем в новом подчиненном потоке с заданными аргументами, способ поиска задается вторым аргументом. Если искомая функция не существует, пропущен обязательный аргумент или заданное количество аргументов слишком велико, будет создано исключение. Созданный поток будет автоматически завершен, если выполнение функции завершится (в т.ч. из-за необработанного исключения), либо если основной поток будет завершен. При завершении подчиненного потока, система не ждет полного окончания завершения, так как оно может занять продолжительное время, если функция выполняет внешний вызов OLE и пр., чтобы убедиться, что поток завершен, можно использовать функцию TerminateThread. Для того, чтобы определить программно, происходит ли исполнение в режиме подчиненного потока, можно использовать функцию IsExecutingInSeparateThread. Функция может быть вызвана для интерфейса Mutex. Некоторые важные свойства функций, исполняемых в отдельных потоках:

  • Если создание такой функции инициировано корневым потоком, функция не будет завершена автоматически и будет находиться в памяти до тех пор, пока клиент не будет закрыт, либо программа не вызовет функцию TerminateThread.
  • Исполняемая функция не обязательно должна быть корневой функцией текущего модуля, возможен, к примеру, вызов функции, подчиненной текущей функции, либо функции родительского или глобального модулей.
  • Функция, исполняемая в отдельном потоке, может вызывать все функции, находящиеся в текущем модуле, однако, она не будет иметь доступа к экспортированным переменным этого модуля (так как исполнение фактически происходит в другом модуле). Для работы с переменными или значениями из вызвавшего модуля, функция может использовать набор своих аргументов или экспортируемые переменные глобальных модулей.
  • В отличие от функции ExecuteFunction, для аргументов функции не будет работать признак ByRef, так как вызвавший поток не ожидает завершения выполнения функции и продолжает работать параллельно с новым.
  • Необработанные исключения внутри функции останавливают ее выполнение, но информация об этих исключениях будет поглощена и выведена в лог не будет (отладчик, однако, будет открыт в момент создания исключения, если режим отладки для визуального клиента разрешен).
  • Исполнение таких функций происходит быстрее, чем вызов новых модулей в отдельных потоках с помощью LoadModule.

Синтаксис

Mutex.ExecuteFunctionInSeparateThread(<Имя функции (STRING)>,<Глубина поиска или компилированная функция (INT, COMPILEDFUNCTION)>=0,<Аргумент 1>,<Аргумент 2>...):<Указатель на среду функции (MUTEX)>

Аргументы

  • <Имя функции (STRING)> - Имя функции, которую необходимо исполнить
  • <Глубина поиска (INT)> - (необязательный аргумент) Может принимать следующие значения:
    • 0 (по умолчанию) -- выполнять поиск по всех модулях большего уровня вложенности (родительских) и во всех глобальных модулях.
    • 1 -- выполнять поиск только внутри текущего модуля.
    • 2 -- выполнять поиск только внутри родительского модуля.
    • 3..x -- выполнять поиск только внутри родительского модуля указанного уровня (к примеру, для уровня 3, выполнять поиск только в родителе родителя текущего модуля).
    • Объект типа компилированная функция -- выполнять поиск функции внутри заданной компилированной функции (только среди функций верхнего уровня).
  • <Аргумент ?> - (необязательный аргумент) Аргументы, передаваемые исполняемой функции

Возвращаемое значение

Возвращает объект семафора, указывающего на новый запущенный поток. В дальнейшем этот объект можно использовать с функциями, типа TerminateThread. Если поток не удалось запустить, по каким-либо причинам, функция либо вызывает исключение, либо отдает объект, для которого функция IsThreadActive возвращает ноль.

Примеры

//Пример выполняет параллельный процесс отправки данных и обновляет индикатор его выполнения

  Function ВыполнитьПроцесс(спДанные)
    Форма:=спДанные.GetByName("Форма");
    TCP:=спДанные.GetByName("Соединение");
    аСтр:=спДанные.GetByName("Данные");
    аВсего:=Length(аСтр);
    аОтослано:=0;
    Фл:=1;
    //Цикл отсылает данные и обновляет текстовое поле на форме
    While Length(аСтр)>0 Do
      аСтр2:=Left(аСтр,1024);
      аСтр:=Mid(аСтр,1025);
      Try
        TCP.SendStrRaw(аСтр2);
      Except
        Фл:=0;
        Break;
      EndTry;
      аОтослано:=аОтослано+Length(аСтр2);
      Форма.оИндикатор.Caption:="Выполнено: "+Round(аОтослано/аВсего,2)+"%";
    EndDo;
    If Фл Then
      Форма.оИндикатор.Caption:="Отправка выполнена успешно!";
    Else
      Форма.оИндикатор.Caption:="Ошибка при отправке!";
    EndIf;
  EndFunction

//Подготовка данных аСтр, соединение с удаленным сервером TCP

спДанные:=List.Create();
спДанные.SetByName("Форма",Form.ThisForm());
спДанные.SetByName("Соединение",TCP);
спДанные.SetByName("Данные",аСтр);
Mutex.ExecuteFunctionInSeparateThread("ВыполнитьПроцесс",0,спДанные);

...