-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Async is not cancelled #320
Comments
In coroutines cancellation is cooperative. The code in your You can make it actually cancellable by using Example: deferred = async {
val conn = URL("http://elitefon.ru/pic/201503/2560x1600/elitefon.ru-38503.jpg").openConnection() as HttpURLConnection
yield() // throw CancellationException if the deferred is cancelled
val bitmap = BitmapFactory.decodeStream(conn.inputStream)
yield() // throw CancellationException if the deferred is cancelled
Log.d("debug", "end of async")
return@async bitmap
} |
@jcornaz, thanks for your answer, but this solution is not suitable for me. Most of the async time relates with BitmapFactory.decodeStream(conn.inputStream) and stream still read after cancelation. I want to interrupt stream reading after cancelation like cancel(true) of android.osAsyncTask. |
Same issue here #173 Don't execute blocking code on common pool (it is really like the UI dispatcher). Use a dedicated Executor and cancel (with interruption) the Future when necessary. |
@fvasco, I add CachedThreadPool as CoroutineDispatcher to async(CachedPool) like this:
But cancelation still not working what I expecting. |
Hi @SamKotlinFisher See also: https://discuss.kotlinlang.org/t/calling-blocking-code-in-coroutines/2368/6 |
@fvasco, thanks for your answer. I developed the similar solution:
What do you think about this? |
Use Future, you can use Guava integration // global executor
val executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool())
private var future: ListenableFuture<Bitmap>? = null
fun onCreate(inState: Bundle?) {
future?.cancel(true)
loadImage()
}
fun loadImage() {
future = executor.submit<Bitmap> {
val bitmap = ...
return@submit bitmap
}
launch(UI) {
future?.await()
...
}
} |
I have a function which load the image by click on button. If button is clicked twice (second click before async completion) it's needed to cancel old async and start new.
Code example:
In this case log will be something like this:
As we can see, in spite of cancel, "end of async" log is called twice.
Also, try/catch logging shown that CancelationException is throws in the launch(UI) block (not the async block).
Can I make it so that if I cancel async, the exception was thrown in the async block?
The text was updated successfully, but these errors were encountered: