def METHOD_NAME(self, options):
    """
    Iterate over all task keyword arguments in random order.
    Randomizing them will help even out the load on the task workers,
    though it will not entirely prevent the possibility of spikes.  It will
    also make the overall time to completion more predictable.
    """
    all_args = []
    estimate_first_attempted = options['estimate_first_attempted']
    for course_key in self._get_course_keys(options):
        # This is a tuple to reduce memory consumption.
        # The dictionaries with their extra overhead will be created
        # and consumed one at a time.
        for task_arg_tuple in tasks._course_task_args(course_key, **options):  # lint-amnesty, pylint: disable=protected-access
            all_args.append(task_arg_tuple)
    all_args.sort(key=lambda x: hashlib.md5(f'{x!r}'.encode('utf-8')).digest())
    for args in all_args:
        yield {
            'course_key': args[0],
            'offset': args[1],
            'batch_size': args[2],
            'estimate_first_attempted': estimate_first_attempted,
        }