美文网首页
GCD之网络请求并发同步

GCD之网络请求并发同步

作者: 大菠萝_b08d | 来源:发表于2020-04-20 14:27 被阅读0次

    今天项目碰到一个网络请求的多线程问题, 为了解决这个问题,翻阅大量文章,最终得到答案,仅以此记录,方便后期回顾和日后再用。

    首先阐述下我遇到的问题,是要上传两张图片到亚马逊,两张上传成功后再请求自己服务器获取合成图片。由于要求图片上传失败即弹出提示重试或者取消的alert,所以在我前期的版本遇到了弹出两次的异常问题。代码如下:

    1.      //创建group

                group=DispatchGroup()

                group.enter()

                uploadParentsPhoto(s3Info: temp.motherS3!.imageInfo)

                group.enter()

                uploadParentsPhoto(s3Info: temp.fatherS3!.imageInfo)

                group.notify(queue: .main, work:DispatchWorkItem(block: {

                    self.requestForBabyForecast(fatherS3: temp.fatherS3!, motherS3: temp.motherS3!)

                }))

    2.

        private func uploadParentsPhoto(s3Info:LES3ImageInfo){

            LEAWSServiceManager.shared().upload(data: s3Info.image.pngData() ??Data(), key: s3Info.key, uploadProgressBlock: { (progress)in

            }) {[weakself] (sucess,error)in

                ifsucess

                {

                    self?.group.leave()

                }

                else

                {

                    //失败的请求

                    ifleterror:NSError= errorasNSError?,error.code==-999

                    {

                        return

                    }

                //失败弹窗

                    self?.alertVC(sureHandler: {[weakself]in

    //do something

                    })

                }

            }

        }

    下面是我在demo上做的一个修改后的逻辑

    @objc private func buttonClick()

           {

    //        let opera1 = BlockOperation {

    //            self.request(para: 1) {

    //

    //            }

    //        }

    //

    //        let opera2 = BlockOperation {

    //            self.request(para: 2) {

    //

    //            }

    //        }

    //

    //        let opera3 = BlockOperation {

    //            self.request(para: 3) {

    //

    //            }

    //        }

    //

    //        opera2.addDependency(opera1)

    //        opera3.addDependency(opera2)

    //        OperationQueue.main.addOperations([opera1,opera2,opera3], waitUntilFinished: false)

            letgroup =DispatchGroup()

            group.enter()

            letsampore =DispatchSemaphore(value:0)

            request(para:1,completion: {

                group.leave()

                sampore.signal()

            })

            _= sampore.wait(timeout: .distantFuture)

            group.enter()

            request(para:2) {

                group.leave()

                sampore.signal()

            }

            _= sampore.wait(timeout: .distantFuture)

            group.enter()

            request(para:3) {

                group.leave()

                sampore.signal()

            }

            _= sampore.wait(timeout: .distantFuture)

            group.notify(queue: .main, work:DispatchWorkItem(block: {

                print("do all finish work")

            }))

        }

        privatefuncrequest(para:Int,completion:@escaping(()->()))

        {

            let  path ="http://www.jianshu.com/p/6930f335adba"

            lettask =URLSession.shared.dataTask(with:URLRequest(url:URL(string: path)!)) { (data, reponse, error)in

                print("request-\(para):finish")

                completion()

            }

            task.resume()

        }

    打印结果为:

    然后我来解释下我个人对这个问题的解决后的理解:

    首先group常常用来处理分组的并发异步事件比较好,而信号量让这些异步的网络请求顺序执行,即a执行完了再去执行b,ab都执行完了,再去执行终极任务c。

    以上是个人理解,可能有偏差,有问题可以@我 lgfprivate@sina.com

    相关文章

      网友评论

          本文标题:GCD之网络请求并发同步

          本文链接:https://www.haomeiwen.com/subject/wozrihtx.html