我正在尝试使用 AFURLSessionManager 在后台将大约 100 张图像上传到 S3,小批量 10 个,就像这里正在做的那样 -管理后台 NSURLSession 中的活动任务的数量
我正在使用共享的 NSURLSession 并在完成某些任务时根据更多任务添加任务。每个文件的平均大小约为 1.6 MB,每个任务队列保证运行的任务数为 5
这是我添加任务的方法:(也可作为更易于阅读的要点)
- (void) addTasksToSessionWithTaskObject:(Task*)taskObject withSessionInitialisationNeeded:(BOOL) needed{
NSString *filePath = [[NSBundle mainBundle] pathForResource:pathForResourceFile ofType:resourceFileType];
S3PutObjectRequest *putObjectRequest = [[S3PutObjectRequest alloc] initWithKey:targetFileKey
inBucket:_bucketname];
putObjectRequest.cannedACL = [S3CannedACL publicReadWrite];
putObjectRequest.filename = filePath;
putObjectRequest.contentType = [resourceFileType isEqualToString:@"MOV"] ? @"movie/mov" : @"image/jpg";
putObjectRequest.endpoint = @"http://s3.amazonaws.com";
putObjectRequest.contentLength=[[[NSFileManager defaultManager]
attributesOfItemAtPath:filePath error:nil] fileSize];
putObjectRequest.delegate = self;
[putObjectRequest configureURLRequest];
NSMutableURLRequest *request = [s3Client signS3Request:putObjectRequest];
NSMutableURLRequest *request2 = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://s3.amazonaws.com/UploadTest/%@",taskObject.fileKey]]];
[request2 setHTTPMethod:request.HTTPMethod];
[request2 setAllHTTPHeaderFields:[request allHTTPHeaderFields]];
if(needed) {
sharedSession = [self backgroundSession];
}
NSURLSessionUploadTask *task = [sharedSession uploadTaskWithRequest:request2 fromFile:forFileUrl];
task.taskDescription = pathForResourceFile;
[currentlyActiveTaskIdArray addObject:@([task taskIdentifier])];
[task resume];
}
这就是我对代表所做的
- (void)URLSession:(NSURLSession *)sessionI task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error{
dispatch_async(dispatch_get_main_queue(), ^{
__block UIBackgroundTaskIdentifier bgTaskI = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bgTaskI];
}];
if([currentlyActiveTaskIdArray containsObject:@([task taskIdentifier])]){
[currentlyActiveTaskIdArray removeObject:@([task taskIdentifier])];
}
if(currentlyActiveTaskIdArray.count < LOWER_SLAB_FOR_TASKS + 1){
[self initiateS3UploadForSetOfTasksIsItBeginningOfUpload:NO];
}
[[UIApplication sharedApplication] endBackgroundTask:bgTaskI];
});
}
这是添加更多任务的代码
- (void) initiateS3UploadForSetOfTasksIsItBeginningOfUpload:(BOOL)beginning{
int i=0;
for(Task *eachTaskObject in tasksArray){
if(i < numberOfTasksTobeAdded){
[self addTasksToSessionWithTaskObject:eachTaskObject WithSessionInitialisationNeeded:NO];
i++;
}
}
}
我一直在前台模式和后台模式下运行 100 个文件的测试。在Foreground模式下,文件以一致、稳定、恒定的速度上传,前3分钟完成90个文件,其余10个文件在20秒内完成。
当我在后台模式下运行应用程序时,我希望它上传前 90 个文件的速度与在 3 分钟的前台窗口中一样快,然后放慢速度……但事实并非如此。在后台模式下,它会在第一分钟上传 15 个文件,然后开始减速……很多。它以越来越慢的间隔开始上传 8 个文件批次:1 分钟、3 分钟、5 分钟、10 分钟,现在是 17 分钟。我们在 46 分钟内有 65 个文件。
有没有办法让它保持快速至少拳头 3 分钟,或者在后台保持一致的速度?
更新:根据 Clay 的评论,我从 AFURLSessionManager 切换回 NSURLSession,因为正如他所指出的,使用基于块的回调是 NSURLSession 的一项极具风险的业务。此外,我还使用了 HTTPMaximumConnectionsPerHost 并将其设置为 10 左右——这给出了更好的结果,但与我想要的结果相去甚远。