TinyTaskHelper
TinyTaskHelper 是 Chameleon 平台提供的轻量级异步任务框架,用于处理耗时较长的后台任务(如大数据导入、复杂计算、外部接口批量调用等),并自动适配平台的进度条 UI 展示。
概述
当业务逻辑需要执行耗时操作时,可以通过 TinyTaskHelper 创建异步任务。平台会自动检测到异步任务并唤起进度条 UI,用户可以实时看到任务执行进度。
核心机制
UI 唤起进度条的关键在于:在返回的响应对象中提供 taskId 属性。平台接口请求监测到响应中包含 taskId 时,会自动唤起进度条并轮询任务状态。
API 方法
StartTask — 启动异步任务
启动一个新的异步任务,同步返回任务信息(任务本身在后台异步执行)。
TinyTaskInfo StartTask(string taskName, Func<TinyTaskContext, Task> taskAction);
| 参数 | 说明 |
|---|---|
| taskName | 任务标题(会显示在进度条上) |
| taskAction | 异步任务执行逻辑,接收 TinyTaskContext 参数 |
返回值: TinyTaskInfo — 最关键的是其中的 Id 属性,需赋给响应对象的 taskId。
GetTaskInfoAsync — 查询任务状态
根据任务 ID 查询任务的最新状态(通常由平台自动轮询调用)。
Task<TinyTaskInfo> GetTaskInfoAsync(string taskId);
TinyTaskContext — 任务上下文
在任务执行过程中,通过 TinyTaskContext 可以实时更新任务状态:
| 方法 | 说明 |
|---|---|
UpdateProgress(int progress) | 直接设置进度值(0-100) |
UpdateProgress(int index, int totalCount) | 根据当前项/总数 自动计算 百分 比进度 |
SetMessage(string message) | 设置状态消息(显示在进度条上) |
SetData(object data, bool save = false) | 设置附加数据(JSON 序列化),save=true 立即持久化 |
Complete(string message = null) | 正常完成任务 |
CompleteWithWarning(string message) | 以警告状态完成(部分成功等场景) |
CompleteWithError(string message) | 以错误状态完成 |
TinyTaskInfo 结构
任务信息的完整结构:
| 属性 | 类型 | 说明 |
|---|---|---|
| Id | string | 任务唯一标识(核心:赋给响应的 taskId) |
| Name | string | 任务名称 |
| IsCompleted | bool | 是否已完成 |
| Progress | int | 当前进度(0-100) |
| StartTime | DateTime | 开始时间 |
| EndTime | DateTime | 结束时间 |
| TimeSpent | string | 耗时时长(格式 hh:mm:ss) |
| HasWarning | bool | 是否有警告 |
| HasError | bool | 是否有错误 |
| Message | string | 状态消息 |
| Data | string | 附加数据(JSON 字符串) |
使用示例
平台接口 C# 脚本(最常用)
在平台接口的 C# 脚本组件中使用,返回 taskId 即可自动触发进度条:
using System;
using System.Threading.Tasks;
using Chameleon.SDK;
using Chameleon.Common;
public class ChameleonCSharpScript
{
public async Task<object> ExecuteAsync(ComponentContext context, ChameleonSDK sdk)
{
// 启动异步任务
var taskInfo = sdk.TinyTaskHelper.StartTask("数据处理任务", async ctx =>
{
for (int i = 0; i < 10; i++)
{
await Task.Delay(1000); // 模拟耗时操作
// 更新进度(自动计算百分比)
ctx.UpdateProgress(i + 1, 10);
}
// 任务正常完成(如无特殊消息可不调用)
ctx.Complete("处理完成");
});
// 关键:将 taskId 赋给响应对象,平台会自动唤起进度条
var res = ResponseResult.Success();
res.taskId = taskInfo.Id;
return res;
}
}
带错误处理的完整示例
public async Task<object> ExecuteAsync(ComponentContext context, ChameleonSDK sdk)
{
var taskInfo = sdk.TinyTaskHelper.StartTask("批量导入用户", async (taskCtx) =>
{
try
{
taskCtx.SetMessage("开始解析文件...");
var users = ParseImportFile(importFileContent);
taskCtx.SetMessage($"共 {users.Count} 条数据,开始导入...");
for (int i = 0; i < users.Count; i++)
{
await SaveUser(users[i]);
taskCtx.UpdateProgress(i + 1, users.Count); // 自动计算百分比
}
taskCtx.Complete($"导入完成,共 {users.Count} 条");
}
catch (Exception ex)
{
taskCtx.CompleteWithError($"导入失败: {ex.Message}");
}
});
var res = ResponseResult.Success();
res.taskId = taskInfo.Id;
return res;
}
带附加数据的任务
任务完成后可将结果数据附加到任务中,供后续查询使用:
var taskInfo = sdk.TinyTaskHelper.StartTask("导出报表", async (taskCtx) =>
{
taskCtx.SetMessage("正在生成报表...");
var reportData = await GenerateReport();
// 将结果数据附加到任务中,save:true 立即持久化
taskCtx.SetData(new { downloadUrl = reportData.Url, rowCount = reportData.Count }, save: true);
taskCtx.Complete("报表生成完成");
});
var res = ResponseResult.Success();
res.taskId = taskInfo.Id;
return res;
// --- 其他地方可通过 taskId 获取结果 ---
// var result = await sdk.TinyTaskHelper.GetTaskInfoAsync(taskInfo.Id);
// var data = JsonConvert.DeserializeObject<MyType>(result.Data);
部分成功的警告场景
当任务部分成功、部分失败时,可标记为警告状态:
sdk.TinyTaskHelper.StartTask("数据同步", async (taskCtx) =>
{
var records = await GetRecordsToSync();
int successCount = 0;
int failCount = 0;
for (int i = 0; i < records.Count; i++)
{
try
{
await CallExternalApi(records[i]);
successCount++;
}
catch
{
failCount++;
}
taskCtx.UpdateProgress(i + 1, records.Count);
}
if (failCount > 0)
{
taskCtx.CompleteWithWarning($"同步完成,成功 {successCount} 条,失败 {failCount} 条");
}
else
{
taskCtx.Complete($"全部同步成功,共 {successCount} 条");
}
});
典型场景
大数据量导入
sdk.TinyTaskHelper.StartTask("批量导入员工", async (taskCtx) =>
{
var employees = ParseImportExcel(fileContent);
taskCtx.SetMessage($"共 {employees.Count} 条记录");
for (int i = 0; i < employees.Count; i++)
{
await sdk.UserInformationHelper.BatchAddUserInformationsAsync(new List<ObjectData> { employees[i] });
taskCtx.UpdateProgress(i + 1, employees.Count);
}
taskCtx.Complete("导入完成");
});
外部接口批量调用
sdk.TinyTaskHelper.StartTask("同步第三方订单", async (taskCtx) =>
{
var orders = await FetchOrdersFromExternal();
int synced = 0;
for (int i = 0; i < orders.Count; i++)
{
await SaveOrder(orders[i]);
synced++;
taskCtx.UpdateProgress(synced, orders.Count);
}
taskCtx.Complete($"同步完成,共 {synced} 条订单");
});
前置条件
| 场景 | 要求 |
|---|---|
| 主站 C# 脚本 | 无需额外配置,直接可用 |
| 微服务中使用 | 主站和微服务站点均需启用 Redis(用于跨进程存储 任务状态和进度) |
| 引用依赖 | 项目需引入 Chameleon.SDK 包 |
| 返回值要求 | 必须在 ResponseResult 中设置 taskId 属性才能触发进度条 |
注意事项
StartTask是同步方法,会立即返回TinyTaskInfo,任务体在后台异步执行- 如果不手动调用
UpdateProgress,进度条会持续等待直到任务完成或超时 - 务必在任务结束时调用
Complete、CompleteWithWarning或CompleteWithError之一 - 如无特殊完成消息,可以不调用
Complete(框架会在任务函数正常结束时默认完成) - 进度值范围是 0-100,推荐使用
UpdateProgress(index, totalCount)让框架自动计算百分比
相关文档
- 异步任务组件 — 平台接口中的异步任务组件配置