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).

Community
  • 1
  • 1
Marian Paździoch
  • 8,813
  • 10
  • 58
  • 103
  • yes, it should probably be volatile – thepoosh Jul 15 '16 at 09:54
  • 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. – chejaras Jul 21 '16 at 16:33
  • Thanks but you comment does not answer the quesiton. – Marian Paździoch Jul 21 '16 at 21:44
  • You are absolutely right to be suspicious of those solutions. They are all quite broken. – G. Blake Meike Jul 23 '16 at 14:47

3 Answers3

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

suitianshi
  • 3,300
  • 1
  • 17
  • 34
  • 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 `AtomicBoolean` – G. Blake Meike Jul 23 '16 at 14:46
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);

    }
Arjun saini
  • 4,223
  • 3
  • 23
  • 51
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

Community
  • 1
  • 1
mangu23
  • 884
  • 9
  • 13