1

I am creating a game where the user interacts with the GUI while the computer finds solutions to the puzzle in a background task. The user can choose to end the game any time, at which point I want to stop my background task and retrieve the solutions it found.

This is all working fine except that I can't force the background task to end when the user chooses?!? When the user selects "Done" I have the following:

computerSolutionTask.cancel(true);

// ...disable some GUI buttons etc...

while (computerSolutionTask.getStatus() != AsyncTask.Status.FINISHED){
   // ...do nothing...
}
txt_computer.setText(computerSolutionTask.get());

And in my AsyncTask class I am checking "isCancelled()" regularly but it just seems to hang in the while loop I included above.

I feel that I may be going about this whole thing a little incorrectly because I don't really want to cancel the background task I just want it to finish wherever it's up to and return what it has.

This thread appears to be asking the same question I am but has no solution...I'm drawing blanks with all my research thus far and any help would be much appreciated.

Community
  • 1
  • 1
MisterWeary
  • 605
  • 1
  • 9
  • 16
  • Don't know android but, on a typical system/OS with only one CPU, code like this would surely hang forever in this loop if the background task had a lower priority than the foreground - the background task would get no CPU at all and so would never check its cancel flag. It would be better to wait on some event that the background task signals when its stopped. The background thread could then wait on an event of its own until you have handled the current results, then you could signal that event to make the background continue. As a test - put a short sleep() in the loop. – Martin James Oct 01 '11 at 07:19
  • Well, I added a sleep in the while loop as you suggested but it still just sat there never finding a "FINISHED" state? I believe the problem is likely to relate to what "K-ballo" mentions below. – MisterWeary Oct 01 '11 at 07:25

2 Answers2

1

A running AsyncTask that is cancelled will never reach onPostExecute and so it will never 'finish'. You don't need to wait for it anyway, if your particular logic requires it use regular synchronization methods.

K-ballo
  • 80,396
  • 20
  • 159
  • 169
  • Outstanding! Thank you so much. I realise now that "cancelling" the task was stopping it giving me anything...so I wrote a public method in my task called `finishMyTask();` that simply stopped my recursive gamesolver where it was. Problem solved – MisterWeary Oct 01 '11 at 07:34
0

You need to put the condition inside the doInBackground() method to check whether the AsyncTask is cancelled or in running state.

 protected Object doInBackground(Object... x) 
    { 
        while (/* condition */)
        {

        // work...

        if (isCancelled())  break;

        } return null; }
Paresh Mayani
  • 127,700
  • 71
  • 241
  • 295
  • 1
    I actually had this and while it did break from the recursive "gameSolver" code I had, it didn't finish it meaning I couldn't get a result back. "K-ballo's" direction above got me on track. Thanks for your assistance though! – MisterWeary Oct 01 '11 at 07:37