3

cfcomponent オブジェクトを呼び出すループがあります。

    <cfset queue_list = "1,2,3">        
    <cfloop list="#queue_list#" index="z">  
                <cfset args = StructNew()>
                <cfset args.group_num = z>          
<cfset args.client_id = 1>          
                <cfset processdownloads = downloader.ProcessDownload(argumentCollection=args)>
            </cfloop>

コンポーネントには次の機能があります。

    <cffunction name="ProcessDownload" access="public" output="false">
        <cfargument name="group_num" type="numeric" required="yes">                     
        <cfargument name="client_id" type="numeric" required="yes">                     

        <cfset variables = arguments>

        <cfthread action="RUN" name="download_#variables.client_id#_#variables.group_num#" priority="high">

                    <cffile action="WRITE" file="#expandpath('download\download_in_process\')##variables.group_num#.json" output="#variables.group_num#">           

</cfthread>

</cffunction>

実行すると、次のエラーが表示されます。

cfthread タグの属性検証エラー。DOWNLOAD_4003_3 という名前のスレッドを作成できませんでした。スレッド名はページ内で一意でなければなりません。
エラーは 29 行目で発生しました。

理由はわかりませんが、2回実行されているようです。一意のスレッド名で新しいスレッドを生成して、トレッド名の競合を回避するべきではありませんか?

4

2 に答える 2

3

group_num を属性として渡して、変数スコープが上書きされる問題を発生させずに内部的にアクセスできるようにします。

<cfthread action="RUN" name="download_#arguments.client_id#_#arguments.group_num#" priority="high" group_num="#arguments.group_num#">
    <cffile action="WRITE" file="#expandpath('download\download_in_process\')##attributes.group_num#.json" output="#attributes.group_num#">           
</cfthread>

問題は変数のスコープです。何が起こっているかというと、各ループが変数スコープを上書きしているため、スレッドが作成されると、変数スコープからスレッド名が取得されます。変数スコープは既に 3 に設定されています...そのため、3 つのスレッドすべてが試行され、同じ値に設定される可能性があります。名前。

引数を使用して名前を付けることができますか? そうでない場合は...ローカルを使用できます。名前を取得し、その情報を CFThread Creation に渡します。

コンポーネントの内部については正しいです。引数などにアクセスすることはできません。これは、コンポーネントの外部とは非常に異なる動作をします。

Ben Nadel は、これらの問題について素晴らしい記事を書きました http://www.bennadel.com/blog/2215-an-experiment-in-passing-variables-into-a-cfthread-tag-by-reference.htm

いつものように勝つためのベン。

于 2015-02-25T00:34:06.003 に答える
0

CFC コードがスレッドセーフでないことが原因である可能性があります。

これ:

<cfset variables = arguments>

関数の引数をオブジェクトの共有スコープにコピーします。オブジェクトがリクエスト間で共有されている場合、downloader各リクエストは他のリクエストの値を使用します。

引数をオブジェクト変数スコープにコピーするのはなぜですか? それは奇妙なことのように思えます。

于 2015-02-24T23:25:12.590 に答える