10

Voglio forzare l'annullamento di AsyncTask. Vedo che è possibile utilizzare isCancelled() come in this valid solution (che sotto il cofano utilizza AtomicBooleanPer forzare l'annullamento AsyncTask non dovrebbe essere volatile la flag periodicamente controllata in doInBackground?

Ma vedo soluzioni come suspiciousSolution1, suspiciousSolution2, suspiciousSolution3 dove c'è nuova bandiera introdotto private boolean isTaskCancelled = false;

E ho iniziato a chiedermi -.. In quanto tale flag è modificato in

public void cancelTask(){ 
    isTaskCancelled = true; 
} 

che gira su un filo, ed è letto in

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

che viene eseguito in WorkerThread, quindi non dovrebbe la bandiera isTaskCancelled essere volatile (o AtomicBoolean come nell'implementazione di Google).

+0

sì, dovrebbe probabilmente essere volatili – thepoosh

+0

Come da linee guida di Google, AsyncTask dovrebbe essere usato per fare molto piccola funzione. Non dovrebbe avere cicli più grandi o compiti più pesanti. Per tali funzionalità utilizzare Gestori e Servizio eseguibile o in background. La bandiera è presente ma verrà convalidata solo all'inizio della condizione if. L'attività può o non può annullare immediatamente come desiderato. – chejaras

+0

Grazie, ma il tuo commento non risponde al quesiton. –

risposta

5

Sì, dovrebbe essere volatile. In caso contrario, una scrittura sulla variabile nel thread A potrebbe non essere visibile a una lettura nel thread B a causa dell'ottimizzazione (da compilatore, JVM, ecc.). Vedere this

+0

Sì. 'doInBackground' è in esecuzione su uno dei numerosi thread in un pool di thread che supporta un Executor. È improbabile che 'cancelTask' venga eseguito dallo stesso thread. Ciò significa che 'isTaskCancelled' è accessibile da più thread e deve essere' volatile'. La stessa struttura 'AsyncTask' usa un' AtomicBoolean' –

2

Try This

inizializzazione

private AysncTask aysncTask; 

Task chiamata

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

Task Cancellare in cui si desidera

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

    }