• 中文
  • 注册
  • 技术交流 技术交流 关注:3 内容:13

    OpenMod插件的任务调度

  • 查看作者
  • 打赏作者
  • 当前位置: 未转变者中文社区 > 技术交流 > 正文
    • 技术交流
    • 搬运自OpenMod官网,经过翻译,可能有些不足,欢迎指正!原文链接

      任务调度

      OpenMod提供AsyncHelper.Schedule方法为了fire-and-forget任务。

      它将给定的任务排队到线程池中。这可用于延迟或定期运行任务。

      通用

      以下示例适用于所有OpenMod平台。

      运行延迟的任务

      您可以这样延迟任务:

      public async Task MyTask(){
          m_Logger.LogInformation("等待5秒...");
          await Task.Delay(TimeSpan.FromSeconds(5));
          m_Logger.LogInformation("完成!");
      }

      那就像这样命名AsyncHelper.Schedule:

      AsyncHelper.Schedule("My Task", () => MyTask());

      定期运行任务

      如果要定期运行任务,只需在任务周围环绕一个while循环:

      public async Task MyPeriodicTask(IOpenModPlugin myPlugin)
      {
          while(myPlugin.IsComponentAlive) // 确保此任务仅在加载插件时运行 
          {
              m_Logger.LogInformation("等待5秒...");
              await Task.Delay(TimeSpan.FromSeconds(5));
              m_Logger.LogInformation("完成!");
          }
      }

      像前面一样命名AsyncHelper.Schedule,但要传递插件实例:

      AsyncHelper.Schedule("My Task", () => MyPeriodicTask(myPlugin));

      在插件卸载后不要让任务继续运行。确保在插件卸载时任务停止运行。您可以使用您的插件IsComponentAlive属性或取消令牌来执行此操作。

      不要使用Thread.Sleep或者类似的阻塞方法,比如任务中的non-async I/O方法。这些方法将阻塞工作线程并阻止其他任务运行。始终使用异步替代方法,例如Task.Delay代替Thread.Sleep或者Stream.ReadAsync文件代替Stream.Read。

      Unity引擎

      以下示例仅适用于使用UnityEngine的游戏,如Unturned。

      在每次更新时运行任务

      定期运行任务的示例一样,我们将再次使用while循环。

      注意返回类型如何更改为UniTask,以及对AsyncHelper.Schedule方法的调用是如何更改的。

      public async UniTask MyUpdateTask(IOpenModPlugin myPlugin){
          await UniTask.SwitchToMainThread(); // 确保先在主线程上运行。
          int i = 0;    while(myPlugin.IsComponentAlive) // 确保此任务仅在加载插件时运行 
          {
              await UniTask.DelayFrame(1, PlayerLoopTiming.Update);
              m_Logger.LogInformation($"Frame update: {++i}");
          }
      }

      让我们把它分解一下。

      检查以下线路:await UniTask.DelayFrame(1, PlayerLoopTiming.Update)

      第一个参数‘1’定义要等待多少帧。因此,这个示例将始终等待一帧,因此在每次帧更新时都会运行。

      第二个参数‘PlayerLoopTiming.Update’设置它应等待的更新类型。在本例中,这是一个普通的帧更新。您也可以使用其他更新类型,例如FixedUpdate。

      以下更新类型可用:

           EarlyUpdate

           LastEarlyUpdate

           FixedUpdate

           LastFixedUpdate

           PreUpdate

           LastPreUpdate

           Update

           LastUpdate

           PreLateUpdate

           LastPreLateUpdate

           PostLateUpdate

           LastPostLateUpdate

      要计划任务,请按以下方式调用AsyncHelper:

      AsyncHelper.Schedule("My Task", () => MyUpdateTask(myPlugin).AsTask() /* 对于UniTask,您必须使用,AsTask() */);

      请登录之后再进行评论

      登录
      极客之爱
      个人签名:收容失效服务器群组QQ群:1037114248
      关注2 粉丝1 喜欢2内容14
      上海
    • 做任务
    • 实时动态
    • 签到中心
      小黑屋
    • 到底部