停止 UI 方法直到异步任务完成

huangapple go评论57阅读模式
英文:

Stop UI-method until Async task is finished

问题

抱歉,我英语不太好。

我正在处理一个需要进行 UI 工作的 Java 类。但是 UI 工作需要等待一个异步任务。这个异步任务从互联网检索 API 信息。一旦 API 信息被检索到,就会被设置为全局变量 jsonResponseBody。然后 UI 方法会使用 jsonResponseBody 来进行 UI 相关的操作。

在我现在的代码中,我使用了一个 while 循环,以便在 jsonResponseBody 准备好之前阻止继续执行。使用 while 循环是否对我来说是一个好主意?我觉得这样做可能会减慢主线程的速度,不是吗?

// 异步任务前的准备工作
connectDbAsync(db, sqlQuery); // 这将在早晚设置好 jsonResponseBody
while (jsonResponseBody == null) {
    // 什么都不做,只是等待
}
// 异步任务完成后的操作,这些操作使用了 jsonResponseBody
英文:

Sorry for me poor english.

i am messing about with a java class that needs to do UI-work. but the UI-work needs to wait for an async task. The asyncTask retrieves api soap from internet. Once api is retrieved it is set to global jsonResponseBody. Then UI-method then uses jsonResponseBody to do UI-stuff.

In my now code, I use while-loop to stop from moving on before jsonResponseBody is ready. Is while-loop best idea for me? I think maybe while-loop will slow down main-thread, no?

    //Pre-async task stuff is run
    connectDbAsync(db,sqlQuery); //This will set jsonResponseBody sooner or later
    while(jsonResponseBody == null){
        //Do nothing, just wait
    }
    //Post-async task stuff which uses jsonResponseBody

答案1

得分: 0

你可以查看一下java Future。你可以使用它来异步启动一些代码,但是你会得到一个处理它的句柄,这样你就可以检查它是否已经完成(Future.isDone()),或者阻塞直到它完成:Future.get()。

英文:

You might have a look at java Future. You can use it to launch some code asynchronously but you get a handle to it and so you can check if it is finished (Future.isDone()) or block until it is finished: Future.get()

答案2

得分: 0

在Java中执行异步任务时,有几种处理输出的方式。如你所发现的一种方式是使用循环阻塞代码执行,直到任务完成。我个人喜欢使用线程池和Future对象来等待线程完成。这两种方法各有优缺点,但在你的情况下,while循环不应该拖慢主线程,因为它只会在有限的时间内运行,并且会在开始执行异步任务后立即运行。

尽管如此,异步任务的好处在于它可以在你的代码执行其他操作时执行自己的任务。如果你必须等待异步任务完成后才能继续方法的执行,那么任务可以同步完成,而不需要循环来暂停执行。

以下是等待多个“站点”网络轮询完成后再继续执行的示例阻塞代码。这展示了在同时执行多个任务时,异步任务/多线程的好处:

// 同时在每个站点上调用run方法,将结果存储在列表中
List<Future> futures = threadmaker.invokeAll(active_sites.stream().map(TAG_SCANNER::new).collect(Collectors.toList()));

List alarm_sites = new ArrayList<>();
// 现在逐个串行获取所有结果
for (Future result : futures) {
// 触发警报操作
alarm_sites.add(result.get());
}
// 继续同步方法执行

英文:

When performing asynchronous tasks in Java there are several ways to handle output. One way as you discovered, is to use a loop to block code execution until the task completes. I personally like to use a thread pool and Future objects to wait on my threads to complete. There are some advantages and disadvantages to both approaches, however in your case, your while loop should not slow your main thread because it only runs for a finite period of time and runs immediately after you start executing your asynchronous task.

That said, the benefit of an asynchronous task is that it can do its thing while your code is doing something else. If you MUST wait on the asynchronous task to complete before continuing on in your method, then the task could be done synchronously instead and you wouldn't need the loop to pause execution.

Example blocking code that waits on network poll of multiple "sites" before continuing execution. This shows the benefit of asynchronous tasks/multithreading when it comes to doing multiple things at one time:

            //Invoke run method on each site simultaneously, store results in a list
            List&lt;Future&lt;Site&gt;&gt; futures=threadmaker.invokeAll(active_sites.stream().map(TAG_SCANNER::new).collect(Collectors.toList()));
        
            List&lt;Site&gt; alarm_sites = new ArrayList&lt;&gt;();
            //Now fetch all the results serially
            for(Future&lt;Site&gt; result: futures){
                //SOUND THE ALARMS
                alarm_sites.add(result.get());
            }
// Continue synchronous method execution

huangapple
  • 本文由 发表于 2020年9月15日 21:29:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/63902949.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定