
只有在程序集任务下才需要编写自己的业务代码，这种方式虽然实施起来比较麻烦，但灵活性更好。

接入流程为：**安装依赖包 -> 开发业务代码 -> 打包上传 -> 创建任务**

<br />

### 安装依赖包

- 编译项目后手动添加引用程序集文件`Hos.ScheduleMaster.Base.dll`。

- 在nuget中搜索`ScheduleMaster`直接安装到项目中。

- 程序包管理控制台中使用`install-package ScheduleMaster`安装。

- 在命令行中使用`dotnet add package ScheduleMaster`安装。


<br />

### 开发业务代码

业务代码类必须继承自任务基类`Hos.ScheduleMaster.Base.TaskBase`，其中的抽象方法`public abstract void Run(TaskContext context);`即是业务执行入口，所以只需要重写这个抽象方法即可。

下面是一个最简单的示例：
``` c#
using System;
using Hos.ScheduleMaster.Base;

namespace Hos.ScheduleMaster.Demo
{
    public class Simple : TaskBase
    {
        public override void Run(TaskContext context)
        {
            context.WriteLog($"当前时间是：{DateTime.Now}");
        }
    }
}
```

#### 读取自定义参数：
``` c#
    public override void Run(TaskContext context)
    {
        context.GetArgument<string>("param1");
        context.GetArgument<int>("param2");
    }
```

#### 使用自定义配置文件：
``` c#
    public override void Initialize()
    {
        //指定配置文件
        base.SetConfigurationFile("myconfig.json");
    }

    public override void Run(TaskContext context)
    {
        context.WriteLog($"我的配置TestKey1：{Configuration["TestKey1"]}");
        context.WriteLog($"我的配置TestKey2：name->{Configuration["TestKey2:Name"]}  age->{Configuration["TestKey2:Age"]}");
    }
```
```json
/* myconfig.json */
{
  "TestKey1": "MyValue1",
  "TestKey2": {
    "Name": "hoho",
    "Age": 18
  }
}
```

#### 上下级任务结果传递：
``` c#
    /// <summary>
    /// 演示如何使用任务依赖关系
    /// </summary>
    public class TaskRef : TaskBase
    {
        public override void Run(TaskContext context)
        {
            //前面可以做具体的业务并得到一个结果，传给后面的任务用
            //.................
            //do something
            //.................
            context.Result = new { success = true, message = "后面的兄弟大家好~" };
        }
    }

    public class TaskRefNext : TaskBase
    {
        public override void Run(TaskContext context)
        {
            context.WriteLog(System.Text.RegularExpressions.Regex.Unescape($"收到了前面的结果：{JsonSerializer.Serialize(context.PreviousResult)}"));
        }
    }
``` 

#### 取消一个长任务：
``` c#
    public class TaskCancel : TaskBase
    {
        public override void Run(TaskContext context)
        {
            Task.Run(() =>
            {
                while (true)
                {
                    if (CancellationToken.IsCancellationRequested)
                    {
                        context.WriteLog("[IsCancellationRequested: true]我要终止运行运行了~");
                        break;
                    }
                    System.Diagnostics.Debug.WriteLine($"{System.Threading.Thread.CurrentThread.ManagedThreadId.ToString()} : {Guid.NewGuid().ToString()}");
                }
            });
        }
    }
```

更多的代码示例可以参考源码中的`Hos.ScheduleMaster.Demo`项目，如果您发现了更好的使用场景，欢迎提PR和大家一起分享。


<br />

### 打包上传


业务代码开发完成后需要把项目编译成dll文件，并以项目名称为文件名把和业务有关的dll文件以及配置文件打包成一个.zip压缩包，您可以选择两种方式进行上传：

- 在控制台创建任务时通过上传入口上传文件包。

- 使用文件传输方式把文件包上传到master进程的`/wwwroot/plugins/`目录下，大文件包推荐这种方式。

在打包和更新文件的过程中有几点要特殊注意下：

- 文件包的命名务必以任务所在的程序集名称命名，否则无法启动。

- 在一个项目中开发了多个任务入口，文件包只需要上传一次即可，但是要注意上传的版本是否覆盖到你所有的任务。

- 任务启动时会默认加载最新的文件包，如果不想使用最新版本可以用系统参数`程序集任务-文件包拉取策略`进行设置。

- 打包时不需要把`Hos.ScheduleMaster.Base.dll`包含进去，否则会启动失败。

- 业务代码尽量减少第三方dll依赖，否则会使得文件包太大导致启动时无法预估的异常。