1

非同期タスクをディスパッチし、すぐに戻るメソッドが必要です。結果を待つ必要はありません。私はこのようなものを動作させたい:

/**
* runs a job and return job id for later montoring.
*/
def int runJob(){
  int jobId = createJob() // returns immediately
  task{
    doSomthingThatTakesSomeTime()
  }.then {stepResult-> doSmtgElse(stepResult)}
  return jobId
}

上記の状況では、 .get() の呼び出しがないため、タスクは実行されませんが、 .get() を実行すると、メソッドはタスクが終了するまで jobId を返しません。

タスクをディスパッチしてすぐに戻るにはどうすればよいですか?

4

2 に答える 2

1

この例を Groovy スクリプトとして実行できます。

    @Grapes(
        @Grab(group='org.codehaus.gpars', module='gpars', version='1.2.1')
    )

    import java.util.concurrent.*
    import groovyx.gpars.*

    def doSomethingThatTakesSomeTime(){
        println "calculating..."
        for(long i: 0..100){
            Thread.sleep(i)
        }

        println "*done*"
        "Done with doSomethingThatTakesSomeTime"
    }

    def doSomethingElse(){
        for(int x:0..1000) print "."
        println "doSomethingElse done."
    }


    /**
    * runs a job and return job id for later montoring.
    */
    def runJob(){
        GParsPool.withPool(){
            Future future = createJob() // returns immediately
            doSomethingElse() //Do someting else while the async process is running
            //Ok, thats done, but the longer runningprocess is still running, return the future
            future
        }
    }

    Future createJob(){
        //create a new closure, which starts the original closure on a thread pool
        Closure asyncFunction = { doSomethingThatTakesSomeTime() }.async()

        //Invoke the function, return a Future
        asyncFunction()
    }

    def job = runJob()
    //println "\n\nResult is: " + job.get()

スクリプトを「そのまま」実行すると、スクリプトが実行され、実行時間の長いジョブが出力*done*され、実際に最後まで実行されたことが示されます。ただし、呼び出しを行う下部の行Future.get()はコメント アウトされており、呼び出されていません。

最後の行のコメントを外すと、呼び出しの結果として完了すると、結果が出力されます。Future.get()

于 2016-03-06T16:14:05.053 に答える
1

@pczeusの回答とJérémie Bのコメントを読んだ後、私はこれを思いつきました:

import static groovyx.gpars.dataflow.Dataflow.task

def int longTask(){
    def counter = 0
    10.times {
        println "longTask_${counter}"
        counter++
        sleep 10
    }
    counter
}

def int getSomeString() {
    def jobId=55
    task {
        longTask()

    }.then { num -> println "completed running ${num} times" }
    return  jobId
}
println getSomeString()

sleep 2000

これは以下を出力します:

longTask_0
55
longTask_1
longTask_2
longTask_3
longTask_4
longTask_5
longTask_6
longTask_7
longTask_8
longTask_9
completed running 10 times

これは私が意図したことです: longTask() はバックグラウンドで実行され、getSomeString() は長いタスクを待たずに再実行され、プログラムがまだ実行されている限り (したがってスリープ 2000)、' then' の部分が実行されます

于 2016-03-06T19:10:59.167 に答える