1

Is there a good way to call an external method after a set time limit for completing the long process outlined below? I would like the long process to stop trying after a set interval and call a method to try something else and wrap up the request.

dispatch_async(dispatch_get_global_queue(0, 0), ^{

    //// LONG PROCESS

    dispatch_async(dispatch_get_main_queue(), ^{

        //// RESULTS PROCESS

    });
});
4
  • 1
    Can you tell us about the nature of the long process? Commented Nov 11, 2014 at 20:02
  • 2
    I would recommend using an NSOperationQueue. Commented Nov 11, 2014 at 20:07
  • It's searching through data. I'm sure there are other ways of going about firing the method call from within the process, but I'm looking for the cleanest and most universal way tied into the code above. Commented Nov 11, 2014 at 20:09
  • The answer depends upon the nature of the "search". Searching some local database? Network requests? Geo search? a little more detail might be helpful. Commented Nov 11, 2014 at 21:25

3 Answers 3

5

In order to "kill" the process that's running your block, you'll have to check a condition. This will allow you to do cleanup. Consider the following modifications:

dispatch_async(dispatch_get_global_queue(0, 0), ^{

  BOOL finished = NO;
  __block BOOL cancelled = NO;
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    if (!finished) {
      cancelled = YES;
    }
  });

  void (^cleanup)() = ^{
    // CLEANUP
  };

  //// LONG PROCESS PORTION #1
  if (cancelled) {
    cleanup();
    return;
  }

  //// LONG PROCESS PORTION #2
  if (cancelled) {
    cleanup();
    return;
  }

  // etc.

  finished = YES;

  dispatch_async(dispatch_get_main_queue(), ^{

    //// RESULTS PROCESS

  });
});
Sign up to request clarification or add additional context in comments.

4 Comments

Same concern as the other answer. Is there a way to double back and cancel dispatch_after before it fires and checks the condition?
I'm not sure what you mean. If the dispatch_after fires after you've finished processing, it sees that finished is YES, so it just exits and does nothing.
Right. But, it's left lingering until it reaches the time specified. Is that eating away system resources needlessly? If this were in a loop, this could be bad news bears... Just curious if there is a good way to cancel the condition checking function's execution before it is called.
You cannot cancel dispatch_after items. I'm not sure this particular one would eat many resources; I didn't profile it, so I'm not 100% sure, but it's not doing much. Presumably if you're expecting the processing in the rest of this process to be long enough on average to necessitate a timeout dispatch_after, you won't be calling it many times in a loop.
3

In the ////Long Process change a boolean value (like BOOL finished) to true when finished. After the call to dispatch_async(...) you typed here, add this:

int64_t delay = 20.0; // In seconds
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC);
dispatch_after(time, dispatch_get_main_queue(), ^(void){
    if (!finished) {
        //// Stop process and timeout
    }
});

In this way, after 20 seconds (or any time you want) you can check if the process is still loading and take some provisions.

3 Comments

Looks good, only problem is that if the process does finish, this still checks if(!finished) after 20 seconds. This could cause problems in a loop situation.
dispach_after will fire off that void function to check the boolean "finished" , would there be a way to double back and terminate the request to fire off that function before it happens? To clean up?
Oh right. In that case the answer from Ian MacDonald is a very good choice!
0

I've used this method for Swift:

let delay = 0.33 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))

dispatch_after(time, dispatch_get_main_queue()) {
     //// RESULTS PROCESS   
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.