Имена динамических потоков ColdFusion - PullRequest
2 голосов
/ 12 марта 2019

Как получить доступ к динамическому имени потока в ColdFusion? Обычно, если я использую имя динамической переменной, я бы сделал что-то вроде этого:

<cfloop from="1" to="10" index="counter" > 
    <cfset Names[counter] = rereplace( createUUID(), "[-_\.]", "", "all") />
    <cfset something[ Names[counter] ] = 1 />
</cfloop>

<cfoutput>
    #( something[ Names[1] ] + something[ Names[2] ] + something[ Names[3] ]  )#
</cfoutput>

Однако попытка сделать это с потоками кажется более хитрой, поскольку я не могу найти способ их создания, кроме использования <cfthread>, которое не позволяет мне создавать поток в качестве члена структуры. Вот что я попробовал:

Попытка 1

<cfloop from="1" to="10" index="counter" > 
    <cfset ThreadNames[counter] = rereplace( createUUID(), "[-_\.]", "", "all") />
    <cfthread action="run" name="#something[ ThreadNames[counter] ]#" > 
        <cfset Thread.something = 1 />
    </cfthread>
</cfloop>

Элемент ... не определен в структуре CFML, на которую ссылаются как на часть выражения.

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

Попытка 2

<cfloop from="1" to="10" index="counter" > 
    <cfset ThreadNames[counter] = rereplace( createUUID(), "[-_\.]", "", "all") />
    <cfthread action="run" name="#ThreadNames[counter]#" > 
        <cfset Thread.something = 1 />
    </cfthread>
</cfloop>

<cfthread action="join" name="#ThreadNames[1]#, #ThreadNames[2]#, #ThreadNames[3]#" />

<cfoutput>
    #( VARIABLES[ThreadNames[1]].something  + VARIABLES[ThreadNames[2]].something  + VARIABLES[ThreadNames[3]].something  )#
</cfoutput>

Элемент ... не определен в Java-объекте типа класса coldfusion.runtime.VariableScope.

Не динамический пример

Для справки, вот как выглядит код перед попыткой добавить uuids

<cfloop from="1" to="10" index="counter" > 
    <cfthread action="run" name="thread#counter#" > 
        <cfset Thread.something = 1 />
    </cfthread>
</cfloop>

<cfthread action="join" name="thread1, thread2, thread3" />

<cfoutput>
    #( thread1.something  + thread2.something  + thread3.something  )#
</cfoutput>

1 Ответ

3 голосов
/ 13 марта 2019

Я обновил этот ответ, чтобы упростить мой пример.Ранее я сохранял имя потока в ключе переменной приложения.Это не нужно, если только вы не хотите хранить значения глобально.Область «переменных» вполне достаточна.

Важно:

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

Реализация:

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

<cfset variables.threadNames = {} />

<cfloop from="1" to="10" index="counter" > 
  <cfset variables.threadName = REReplace(CreateUUID(), "[-]", "", "all") />
  <cfthread action="run" name="#variables.threadName#" threadName="#variables.threadName#" counter="#counter#"> 
    <cfset thread.something = attributes.counter />
    <cfset variables.threadNames[attributes.threadName] = thread.something />
  </cfthread>
</cfloop>

<cfthread action="join" name="#StructKeyList(variables.threadNames)#" timeout="6000" />

<cfloop collection="#variables.threadNames#" item="key">
  <cfset variables.thread = cfthread[key]>
  <cfdump var="#variables.thread#" />
</cfloop>
...