简体   繁体   English

保证回调始终是异步执行的最佳方法?

[英]Best way to guarantee a callback is always executed asynchronously?

I'm working an Android app that has to make server request and then perform actions when the request is completed. 我正在使用一个Android应用程序,该应用程序必须发出服务器请求,然后在请求完成时执行操作。 Here's some pseudo code to help explain the situation: 这是一些伪代码来帮助解释这种情况:

makeRequest(new SomeTask{
    onDone() {
        // Do actionB with queue
    }
});

// Do actionA with queue.  Must be execute first!!

Here's the implementation of makeRequest in pseudo code: 这是伪代码中的makeRequest的实现:

makeRequest(SomeTask task) {
    if(canDoOptimization) { // if true, don't need to make request

        // It's a bad idea to execute this immediately.
        // Wish I could wait until the current thread of execution was done...
        task.onDone();
        return;
    }

    asyncTask = new AsyncTask<SomeTask, Void, Void>() {
        doInBackground(SomeTask... task) {
            // Make server request...

            task.onDone();
        }
    }
    asyncTask.execute(task);
}

Usually actionA happens before actionB as expected, but in cases where we can avoid a network requests, SomeTask.execute is called immediately. 通常, actionA会按预期在actionB之前发生,但是在可以避免网络请求的情况下,会立即调用SomeTask.execute This causes actionB to occur before actionA , which is bad. 这导致actionB actionA 之前 actionA ,这是不好的。 Is there any way I can guarantee this doesn't happen? 有什么办法可以保证不会发生这种情况吗?

I've run into this situation several times in javascript. 我在javascript中多次遇到这种情况。 In those cases, I would wrap the SomeTask.execute call with a setTimeout or setImmediate to maintain the proper async semantics. 在这些情况下,我将使用setTimeoutsetImmediate包装SomeTask.execute调用以维护适当的异步语义。

For clarity, here's an example of the same bug in JavaScript: https://gist.github.com/xavi-/5882483 为了清楚起见,下面是JavaScript中相同错误的示例: https : //gist.github.com/xavi-/5882483

Any idea what I should do in Java/Android? 知道我应该在Java / Android中做什么吗?

Welcome to world of synchronization. 欢迎来到同步世界。 Mutex or lock objects are often used for that purpose. 互斥锁或锁定对象通常用于此目的。 Is there a Mutex in Java? Java中是否有Mutex?

your B task should wait on mutex which is to be signaled by task A upon its completion. 您的B任务应等待互斥量,而互斥量将在任务A完成时发出信号。 That will ensure proper execution order where A task will finish before B. 这将确保正确的执行顺序,其中A任务将在B之前完成。

Always put task.onDone() in the AsyncTask , even if it doesn't have to make a request. 始终将task.onDone()放在AsyncTask ,即使它不必发出请求也是如此。

makeRequest(SomeTask task) {

    asyncTask = new AsyncTask<SomeTask, Void, Void>() {
        void doInBackground(SomeTask... task) {

            if(canDoOptimization) { // if true, don't need to make request

                // It's a bad idea to execute this immediately.
                // Wish I could wait until the current thread of was done...
                task.onDone();
                return;
            } else {
                // Make server request...

                task.onDone();
            }
        }
    }
    asyncTask.execute(task);
}

Why can't you just switch the order of things? 您为什么不能只切换事物顺序?

// Do actionA with queue.  Must be execute first!!

makeRequest(new SomeTask{
onDone() {
    // Do actionB with queue
});

If actionA is asynchronous as well and performed on a separate AsyncTask, you can call makeRequest(...) on actionA's AsyncTasks's onPostExecute() method. 如果actionA也是异步的并且在单独的AsyncTask上执行,则可以在actionA的AsyncTasks的onPostExecute()方法上调用makeRequest(...)。

And btw, since Android Honeycomb version, AsyncTasks are ran on the same thread, meaning if you have several tasks they can block each other. 顺便说一句,从Android Honeycomb版本开始,AsyncTasks在同一线程上运行,这意味着如果您有多个任务,它们可能会相互阻塞。 This is fixed by specifying that the AsyncTsak should run in a thread pool: 通过指定AsyncTsak应该在线程池中运行来解决此问题:

if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) {
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
  asyncTask.execute();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将始终执行CompletableFuture回调 - will CompletableFuture callback always be executed Futures.addCallback如何保证回调在执行未来任务的线程上执行? - how Futures.addCallback guarantee the callback to be executed at the thread executing the future task? 在Android中异步执行方法的最佳方法(紧凑和正确) - Best way to execute method asynchronously in Android (compact and correct) Java保证回调订单执行 - Java guarantee callback order execution 是否将FutureCallbacks添加到ListenableFuture异步执行? - Are FutureCallbacks added to the ListenableFuture executed asynchronously? 确保并发Web服务调用之间的数据一致性的最佳方法? - Best performing way to guarantee data consistency between concurrent web service calls? 在列表视图中使用回调异步加载图像 - Loading images in listview asynchronously with callback 在高性能Java应用程序中异步处理低速使用者(数据库)的最佳方法是什么 - What's the best way to asynchronously handle low-speed consumer (database) in high performance Java application 如果我将@Async 方法放在一个方面会异步执行吗? - Will an aspect be executed asynchronously if I put @Async method on it? 完成`FusedLocationClientProvider`的`removeLocationUpdates`后接收回调的最佳方法是什么? - What is the best way to receive a callback on completion of `removeLocationUpdates` of `FusedLocationClientProvider`
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM