GCD - dispatch_barrier_async - 等待完成

时间:2012-09-21 16:55:36

标签: objective-c grand-central-dispatch

我有这个代码

-(void) Method {

    // WAIT_CODE

    dispatch_async(myQueue,^{ CODE 1});
    dispatch_async(myQueue,^{ CODE 2});  
    dispatch_barrier_async(myQueue,^{
        // SOME CODE
        dispatch_async(dispatch_get_main_queue(), ^{GUI UPDATE }
    });
}

问题是,当我再次调用此方法并且尚未执行某些代码时,我需要在继续之前等待WAIT_CODE(但GUI必须保持活动状态)...我该怎么做?

3 个答案:

答案 0 :(得分:1)

选项1) 添加第二个串行队列是否有意义,因此只有在没有对该方法执行其他调用时才运行-method中的代码?

例如,在调用者中你会有:

mySerialQueue = dispatch_queue_create("com.myapp.my-serial-queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(mySerialQueue, [self method]);

选项2) 使myQueue串行而不是并发(我假设它是并发的,因为dispatch_barrier_async()仅适用于您拥有的并发队列)。

myQueue = dispatch_queue_create("com.myapp.myqueue", DISPATCH_QUEUE_SERIAL);    
dispatch_async(myQueue,^{ CODE 1});
dispatch_async(myQueue,^{ CODE 2});  
dispatch_async(myQueue,^{
   SOME CODE
   dispatch_async(myQueue,^{
      WAIT_CODE
      dispatch_async(dispatch_get_main_queue(), ^{GUI UPDATE }
   });
});

选项3) 重新排序代码以在SOME_CODE

之后添加WAIT_CODE
dispatch_async(myQueue,^{ CODE 1});
dispatch_async(myQueue,^{ CODE 2});  
dispatch_barrier_async(myQueue,^{
    SOME CODE  // this code must block
    WAIT_CODE  // this code must block
    dispatch_async(dispatch_get_main_queue(), ^{ GUI UPDATE }
});

答案 1 :(得分:1)

你想做什么?

你为什么要等?

如果再次调用此函数时队列仍在执行SOME CODE,那么这些“新”块将被排队,并且在SOME CODE块运行之后才会执行。我假设myQueue是并发队列。屏障调用将等待所有先前排队的块在运行之前执行。此外,它将是队列上运行的唯一块,直到完成,然后队列将同时恢复执行块。

答案 2 :(得分:1)

您还可以使用信号量进行同步。以下是您的代码的结构。

-(void) Method 
{

  // Declared dispatch_semaphore_t _synch;
  // in init: _synch = dispatch_semaphore_create(1);
  // in dealloc: dispatch_release(_synch);
  //
  // Initialized with 1 so first call goes through.
  // Subsequent calls are serialized and must wait on a signal.
  //
  dispatch_time_t blockingSleepSecondsIfNotDone = 0.01;
  while (!dispatch_semaphore_wait(wait, DISPATCH_TIME_NOW))
      usleep(USEC_PER_SEC * blockingSleepSecondsIfNotDone);

  WAIT_CODE

  dispatch_async(myQueue,^{ CODE 1});
  dispatch_async(myQueue,^{ CODE 2});  
  dispatch_barrier_async(myQueue,^{
    SOME CODE
    dispatch_semaphore_signal(_synch);
    dispatch_async(dispatch_get_main_queue(), ^{GUI UPDATE }
  });
}