title: In a macOS Application, I have a background thread executing with one single line of code taking a lot of time. How to cancel the block?
body: <p>In a Cocoa Objective-C Application that I am developing, I have a NSTableView with a delegate that implements tableViewSelectionDidChange. In the delegate implementation of the method, I have put a background serial queue implemented with GCD that handles loading the currently selected object in the table for it to display in a details NSView that is to the right of the table. My desired behaviour would be that if the background thread has not finished and there is a new selection in the left table, I would like to cancel it and start a new thread for the new selection. I have found a very elegant solution using GCD <a href="https://mattrajca.com/2016/04/23/canceling-blocks-in-gcd.html" rel="nofollow noreferrer">here</a> that uses: </p>
  
  <pre><code>dispatch_block_cancel(work);
  </code></pre>
  
  <p>The problem is that, like it is said in the link:</p>
  
  <p>"One thing to note is that dispatch_block_cancel is not pre-emptive. If the worker block is in the middle of a long-running operation, dispatch_block_cancel won't force-terminate it. To do this, we have to periodically test for cancellation with dispatch_block_testcancel. Here's an example:"</p>
  
  <pre><code>for (...) {
      /* do some work */
      [NSThread sleepForTimeInterval:0.2];
  
      if (dispatch_block_testcancel(work) != 0) {
          /* exit gracefully */
          return;
      }
  }
  </code></pre>
  
  <p>The problem is that in my application, the most lengthy operation performed in the tableViewSelectionDidChange implementation is in a single line of code and I cannot refactor my code to change this because that statement is calling an external dylib that I am using. In this case I cannot check if the block is cancelled with: </p>
  
  <pre><code>if (dispatch_block_testcancel(work) != 0) {
          /* exit gracefully */
          return;
  }
  </code></pre>
  
  <p>because the thread is blocked on a lengthy one line operation. Can somebody hopefully suggest a strategy of some kind, preferably still using GCD ? I am aware of NSOperation and NSOperationQueue, but before learning to use them, I would like to be certain they do not have problems cancelling operations in the middle of a 1 line statement like GCD apparently does. Thanks a lot for any help.</p>