To force cancel AsyncTask shouldn't the flag periodically checked in doInBackground be volatile?
Asked Answered
T

3

10

I want to force cancel AsyncTask. I see that you can use isCancelled() like in this valid solution (which under the hood uses AtomicBoolean.

But I see solutions like suspiciousSolution1, suspiciousSolution2, suspiciousSolution3 where there is new flag introduced private boolean isTaskCancelled = false;.

And I started wondering - since that flag is modified in

public void cancelTask(){
   isTaskCancelled = true;
}

which runs on SOME thread, and is read in

protected Void doInBackground( Void... ignoredParams ) {
    //Do some stuff
    if (isTaskCancelled()){
        return;
    }
}

which runs in WorkerThread, then shouldn't the flag isTaskCancelled be volatile (or AtomicBoolean as in Google's implementation).

Touristy answered 15/7, 2016 at 9:32 Comment(4)
yes, it should probably be volatileFoudroyant
As per google guidelines, AsyncTask should be used for doing very small function. It should not be running bigger loops or heavier tasks. For such features either use Handlers and Runnable or Background Service. The flag is present but it would be validated only at the start of your if condition. The task may or may not cancel immediately as desired.Riband
Thanks but you comment does not answer the quesiton.Hypotrachelium
You are absolutely right to be suspicious of those solutions. They are all quite broken.Cheviot
M
5

Yes, it should be volatile. Otherwise a write to the variable in thread A may not be visible to a read in thread B due to optimizaton(by compiler, JVM, etc). See this

Magaretmagas answered 22/7, 2016 at 5:51 Comment(1)
Yes. doInBackground is being run on one of several threads in a thread pool backing an Executor. It is unlikely that cancelTask will be run from the same thread. That means that isTaskCancelled is accessed from multiple threads and must be volatile. The AsyncTask framework itself uses an AtomicBooleanCheviot
J
2

Try This

Initialize

  private AysncTask aysncTask;

Task Call

   aysncTask=new AysncTask();
        aysncTask.execute();

Task Cancel Where You WANT

  if ( aysncTask != null && aysncTask.getStatus() == aysncTask.Status.RUNNING ){
        aysncTask.cancel(true);

    }
Justiciary answered 22/7, 2016 at 6:13 Comment(0)
C
0

Yes, volatile. Considering that you are only using this to periodically check your asynctask. If it were multiple threads I would suggest using atomic fields. Pls see more information here: volatile vs atomic & Volatile boolean vs AtomicBoolean

Contemn answered 21/7, 2016 at 16:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.