• 注册
  • 技术交流 技术交流 关注:9 内容:20

    [OpenMod]插件的任务调度

  • 查看作者
  • 打赏作者
  • 当前位置: 未转变者中文社区 > 技术交流 > 正文
    大版主
    Lv.15

    搬运自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() */);

    请登录之后再进行评论

    登录
  • 发布内容
  • 任务中心
  • 实时动态
  • 偏好设置
  • 帖子间隔 侧栏位置: