class_docstr: Object that is responsible for evaluating asynchronous multiple agents.
  
  Args:
      n_steps (int): Number of timesteps used in each evaluation.
      n_episodes (int): Number of episodes used in each evaluation.
      eval_interval (int): Interval of evaluations in steps.
      outdir (str): Path to a directory to save things.
      max_episode_len (int): Maximum length of episodes used in evaluations.
      step_offset (int): Offset of steps used to schedule evaluations.
      save_best_so_far_agent (bool): If set to True, after each evaluation,
          if the score (= mean return of evaluation episodes) exceeds
          the best-so-far score, the current agent is saved.
class_docstr_tok: ["Object","that","is","responsible","for","evaluating","asynchronous","multiple","agents",".","Args",":","n_steps","(","int",")",":","Number","of","timesteps","used","in","each","evaluation",".","n_episodes","(","int",")",":","Number","of","episodes","used","in","each","evaluation",".","eval_interval","(","int",")",":","Interval","of","evaluations","in","steps",".","outdir","(","str",")",":","Path","to","a","directory","to","save","things",".","max_episode_len","(","int",")",":","Maximum","length","of","episodes","used","in","evaluations",".","step_offset","(","int",")",":","Offset","of","steps","used","to","schedule","evaluations",".","save_best_so_far_agent","(","bool",")",":","If","set","to","True",",","after","each","evaluation",",","if","the","score","(","=","mean","return","of","evaluation","episodes",")","exceeds","the","best-so-far","score",",","the","current","agent","is","saved","."]
code: def evaluate_if_necessary(self, t, episodes, env, agent):
      necessary = False
      with self.prev_eval_t.get_lock():
          if t >= self.prev_eval_t.value + self.eval_interval:
              necessary = True
              self.prev_eval_t.value += self.eval_interval
      if necessary:
          with self.wrote_header.get_lock():
              if not self.wrote_header.value:
                  self.write_header(agent)
                  self.wrote_header.value = True
          return self.evaluate_and_update_max_score(
              t, episodes, env, agent
          )
      return None
  
imports: import logging
  import multiprocessing
  import os
  import statistics
  import time
  import numpy
  import chainerrl
label_desc: Use image node_id 5 for calling the AsyncEvaluator obj's underlying member method code with example usage: obj.evaluate_if_necessary(t, episodes, env, agent) and returns: None, self