views:

107

answers:

3

Calling instance method cancel on an NSURLConnection most often don't cancel the connection at all.

I'm performing an asynchronous NSURLConnection in an NSOperation. If the operation is cancelled, the connection is stopped by calling cancel on NSURLConnection and then setting the connection to nil.

Is there a way to cancel the connection immediatly? Most often it continues running in the background until the request is finished even though both the connection is canceled and set to nil. The NSOperation subclass is dealloced after the connection is canceled, where the connection is released. Even after that, the asynchronous connection continues running!

Is there another way to cancel it? Or can the thread its running on be canceled?

Here is a code snippet from my NSOperation subclass main method:

      // Create and start asynchronous connection
      self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
      [request release];

      while(!isFinished) {
          if(self.isCancelled) {
             [self.connection cancel];
             self.connection = nil; 
             [self uploadCanceledDelegate];
             return;
          }

          // Special sleep because callbacks are executed on same thread as this loop
          [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
      }

NOTE: This behaviour only occur when WiFi is enabled. With 3G/Edge/GPRS it works fine

A: 

I don't know.

I'm using this library http://allseeing-i.com/ASIHTTPRequest/ :-)

Maybe you should take a look ;-)

Good Luck !

Vinzius
+1  A: 

This might be a problem with Apple's documentation.

It's possible that the connection is currently waiting in a blocked thread, and there's nothing the OS will do immediately while that thread is blocked. The thread won't really be canceled until it becomes unblocked at some later point in time. Therefore you should not release any objects handling those cancelled connections until some unknown point in the future when the socket the thread is waiting on times out or is closed.

If you are experiencing leaks or crashes, you might try moving the "cancelled" operation objects to another queue of stuff waiting to be released a few seconds or maybe even minutes later.

hotpaw2
Thanks for your reply! Currently i'm not experience any leaks or crashes.
Marcus
It seems like the thread performing the asynchronous connection is being blocked until it itself checks for cancel or is finished and there is nothing you can do about it. And when it transfers smaller amount of data (2mb) at high speed (WiFi), sometimes the thread reaches finish and doesnt check if its cancelled. I'm marking this as the correct answer now. Thanks!
Marcus
A: 

This could be because cancel is a message and the message dispatcher cannot dispatch the message while the current function is in the while loop. I hope my understanding of Objective C messages is correct here, but this might work if you allow the function to finish and handle other cleanup code in a callback that fires when your isFinished flag is set. I'm prepared to be wrong but I think the problem might be the while loop.

gavin
Thanks for your answer! The while loop ends after cancel is called so i don't think thats the problem.
Marcus