Очереди отправки: Как сказать, работают ли они и как остановить их

Это - действительно спецификация требований и проблема управления. Я дал бы им вообще, Вы имеете. Попытайтесь описать его ясно на простом английском языке (или независимо от того, что язык является соответствующим). Если Вы можете блок-схема, сделать это также.

необходимо ожидать, что программист, возможно, задаст несколько вопросов и затем уйдет для размышления, но Вы должны также , ожидают их возвратиться с большим количеством вопросов для Вас, разъяснить требования. Если они не делают этого в течение приблизительно одной недели, необходимо перепроверить с ними, чтобы дать им возможность спросить.

, Если проект поддается ему, Вы могли бы настроить для наблюдения рано, рабочие прототипы.

33
задан Abizern 20 October 2009 в 11:16
поделиться

1 ответ

This is a semi-common question when programming with GCD.

The short answer is that GCD does not have a cancelation API for queues. The rationale:

  1. memory management would become vastly more complicated, because a given block might be responsible for free()ing a given allocation of memory. By always running the block, GCD ensures that memory management remains easy.
  2. It is practically impossible to halt a running block without corrupting state.
  3. Most code that needs cancellation logic is already tracking that state in private data structures.

Given all of these cases, it is far more efficient and powerful to write code like this:

dispatch_async(my_obj->queue, ^{
    bool done = false;
    // do_full_update() takes too long, therefore:
    while ( !my_obj->cancelled && !done ) {
        done = do_partial_update(my_obj);
    }
});

Oh, and to know if a queue has finished running all of the enqueued blocks, your code can simply execute an empty block with the synchronous API:

dispatch_sync(my_obj->queue, ^{});

As mentioned in the comments, a better way of knowing when your work is done is to use dispatch groups. Dispatch all your blocks to the group and then you can add a completion handler to the group. Once the work is complete, the completion block will run.

dispatch_group_t myGroup = dispatch_group_create();
dispatch_group_async(myGroup, my_obj->queue, ^{
    bool done = false;
    while ( !my_obj->cancelled && !done ) {
        done = do_partial_update(my_obj);
    }
});
dispatch_group_notify(myGroup, my_obj->queue, ^{
    NSLog(@"Work is done!");
    dispatch_release(myGroup);
});

Once all of your blocks have completed, the group will be empty and trigger the notification block. From there, you can update UI, etc.

Good luck and have fun!

49
ответ дан 27 November 2019 в 18:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: