Using semaphore to block many, then release all
我有多个异步任务,所有这些任务都取决于初始的异步身份验证步骤才能成功。我正在使用信号量阻止所有安全任务,直到身份验证完成。它主要用于计时目的,因为任务依赖于身份验证结束时获得的安全令牌。身份验证涉及网络请求,可能需要几秒钟的时间。
下面我的代码中的困难似乎是在身份验证后发出的
我想知道是否有更干净的方法来进行此阻止。我相信每个等待的任务都可以立即发出另一个
是否有使用GCD的更干净的方法?我不熟悉GCD,因此在以下用法的背景下,代码段会有所帮助。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | dispatch_semaphore_t sem = dispatch_semaphore_create(0); // in actuality, these 3 may be any where in the app, in different classes, methods, etc // so a completionHandler is not possible [self authentication]; // async, could take many seconds [self authenticatedTask1]; // async [self authenticatedTask2]; // async - (void) authentication { // async url request, assume it is configured here [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){ // authenticate authenticated = TRUE; secure_token = @"4rjiofwefsdf"; // obtained during auth dispatch_semaphore_signal(sem); }]; } - (void) authenticatedTask1 { // put on new thread, so semaphore doesn't block program dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ if(!authenticated){ // wait until authenticated dispatch_semaphore_wait(sem) } // continue after authenticated, using secure_token }); } - (void) authenticatedTask2 { // put on new thread, so semaphore doesn't block program dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ if(!authenticated){ // wait until authenticated dispatch_semaphore_wait(sem) } // continue after authenticated, using secure_token }); } |
您可以将经过身份验证的任务放入其自己的挂起的调度队列中,并在身份验证成功后恢复调度队列。
这不是很优雅,但是您可以在" dispatch_semaphore_wait "之后立即调用" dispatch_semaphore_waital"。它应该可以解决问题。
1 2 3 4 5 6 7 8 9 10 11 | - (void)authenticatedTask1 { // put on new thread, so semaphore doesn't block program dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ if(!authenticated){ // wait until authenticated dispatch_semaphore_wait(sem); dispatch_semaphore_signal(sem); // !!! } // continue after authenticated, using secure_token }); } |
您可以将要在块中执行的方法传递给要在completltion块中运行的方法,那么您就不需要使用信号量。同样,您也无需费心
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [self authenticationWithCompletionBlock:^{ [self authenticatedTask1]; [self authenticatedTask2]; }]; - (void) authenticationWithCompletionBlock:(dispatch_block_t)block { // async url request, assume it is configured here [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){ // authenticate authenticated = TRUE; secure_token = @"4rjiofwefsdf"; // obtained during auth block(); }]; } |
如果方法在同一类中,则可以直接调用方法而不是块。
如果您需要知道两个异步任务(在您的情况下为