3

I have an NSOperation used to copy files. I copy files using write() and then have the ability between each write() to "pause" the copy. However I do not know how to:

  • Tell the operation that it should pause (from the UI main thread)
  • Pause the operation (I think that a "while (isPaused==YES)" is not the right option
  • Tell the operation to continue

Thanks for your help

AP.
  • 5,205
  • 7
  • 50
  • 94
  • 1
    You could make each operation create another operation for each chunk of the file. Each copy-chunk operation would depend on the one before it, and the copy-whole-file operation would create an operation queue and put all the copy-chunk operations into it. When you pause the copy-file operation, it would suspend its copy-chunks operation queue. – Peter Hosey Dec 22 '11 at 17:18

2 Answers2

2

You can do this with a semaphore; but rather than using the semaphore to control access to a section of code (i.e. acquire the lock, use the resource, release the lock model) you instead just think of it as a gate - acquire, test condition/block, release and continue.

NSCondition will give you a high-level semaphore. In the overview there step 3 is "test if I should pause" and steps 4 & 5 become "no, so do nothing".

CRD
  • 52,522
  • 5
  • 70
  • 86
0

I'll recap on the beautiful comment, with a little "philosophy" in advance.

Use of NSOperation queues came first and foremost to RID US from the need to semaphore, to trigger, to watch for triggers, to poll on conditions and all that.

If you find yourself meddling with these "old style" concurrency issues, you are most likely on the wrong trail, off the NSOperationQueue road. It MUST be simple. it MUST be without "threading edges".

The important point is: you do NOT pause an NSOperation. You pause an NSOperationQueue. When paused, the queue will let executing operations finish - but will not dequeue more operations, until the queue is resumed.

This implies breaking your long NSOperation "that copies files using write()" into several "smaller" NSOperations. Maybe one per-file, or, if you need to pause the copying of a single-file in the middle - have each NSOperation responsible for a specific write() call.

To order and synchronize these smaller NSOperations you can put to use the huge arsenal of tools packed with NSOperationQueue and NSOperation.

  • You can use dependencies to order of execution of the chain. and to maintain several concurrent chains.
  • You can use cancellation to break a chain and stop it.
  • You can simply pause and resume the NSOperationQueue to achieve your effect, knowing that each NSOperation of yours (say copying 100KB of file data) is handled correctly.
  • You can get your "progress" for free using NSProgress that is so nicely integrated with NSOperationQueue.
  • You can offload "dependent" operations to other queues of higher or lower priorities, to optimize your performance (say one for the higher-level UI handling, and one for the lower-level file-system manipulations.

It is really endless and very easy to do.

Last - if you want to enjoy "better dependency" mechanism than what NSOperation gives out of the box - look at my own question here and read both the beautiful answers by others, and my own take of the problem there.

Motti Shneor
  • 2,095
  • 1
  • 18
  • 24