code: def WaitForTasks(tasks,
                   raiseOnError=True,
                   si=None,
                   pc=None,
                   onProgressUpdate=None,
                   results=None):
      
  
      if not tasks:
          return
  
      if si is None:
          si = vim.ServiceInstance("ServiceInstance", tasks[0]._stub)
      if pc is None:
          pc = si.content.propertyCollector
      if results is None:
          results = []
  
      progressUpdaters = {}
      for task in tasks:
          progressUpdater = ProgressUpdater(task, onProgressUpdate)
          progressUpdater.Update('created')
          progressUpdaters[str(task)] = progressUpdater
  
      filter = CreateTasksFilter(pc, tasks)
  
      try:
          version, state = None, None
  
          # Loop looking for updates till the state moves to a completed state.
          while len(progressUpdaters):
              update = pc.WaitForUpdates(version)
              for filterSet in update.filterSet:
                  for objSet in filterSet.objectSet:
                      task = objSet.obj
                      taskId = str(task)
                      for change in objSet.changeSet:
                          if change.name == 'info':
                              state = change.val.state
                          elif change.name == 'info.state':
                              state = change.val
                          else:
                              continue
  
                          progressUpdater = progressUpdaters.get(taskId)
                          if not progressUpdater:
                              continue
  
                          if state == vim.TaskInfo.State.success:
                              progressUpdater.Update('completed')
                              progressUpdaters.pop(taskId)
                              # cache the results, as task objects could expire if one
                              # of the tasks take a longer time to complete
                              results.append(task.info.result)
                          elif state == vim.TaskInfo.State.error:
                              err = task.info.error
                              progressUpdater.Update('error: %s' % str(err))
                              if raiseOnError:
                                  raise err
                              else:
                                  print("Task %s reported error: %s" % (taskId, str(err)))
                                  progressUpdaters.pop(taskId)
                          else:
                              if onProgressUpdate:
                                  progressUpdater.UpdateIfNeeded()
              # Move to next version
              version = update.version
      finally:
          if filter:
              filter.Destroy()
      return
docs: Wait for mulitiple tasks to complete. Much faster than calling WaitForTask
      N times