You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用同一类存储函数多次运行产生的数据

优化方案:解决Ajax多次请求的数据持久化与代码冗余问题

你的问题其实核心是两个痛点:HTTP请求的无状态性导致每次请求都初始化新的类实例,之前的数据无法留存;当前的存储类设计过于冗余,新增训练次数就要加类和判断分支,扩展性极差。下面给你一套更简洁、可扩展的实现方案:


1. 重构存储类:用通用结构替代多个重复类

完全不需要为每个训练ID单独创建类,我们可以用一个通用的存储结构,比如字典(Dictionary<int, string>)直接存储不同训练ID对应的数据,或者定义一个简单的实体类来封装:

方案1:直接用字典(最简洁)

不需要额外定义类,直接用Dictionary<int, string>键值对,键是训练ID(sintraining的值),值是收集到的数据。

方案2:定义通用实体类(如果需要扩展更多字段)

如果之后需要给每条记录加时间戳、用户标识等字段,可以定义一个实体类:

public class HandGestureRecord
{
    public int TrainingId { get; set; }
    public string Data { get; set; }
    public DateTime RecordTime { get; set; } = DateTime.Now; // 可选:记录数据收集时间
}

然后用List<HandGestureRecord>或者Dictionary<int, HandGestureRecord>来存储。


2. 解决数据持久化问题:利用Session/静态变量/临时存储

因为HTTP请求是无状态的,每次请求都会创建新的Action实例,所以局部变量的类实例会在请求结束后销毁。我们需要选择适合的持久化方式:

推荐:用Session做用户隔离的存储

如果是每个用户独立收集自己的数据,Session是最合适的,它会为每个用户维护独立的存储区域:

[HttpPost]
public ActionResult ReadsSerial(string sintraining)
{
    // 1. 安全解析训练ID:用TryParse替代try-catch更优雅
    if (!int.TryParse(sintraining, out int trainingId))
    {
        Console.WriteLine($"Unable to parse '{sintraining}'");
        return BadRequest("Invalid training ID format");
    }

    // 2. 从Session获取或初始化数据存储字典
    var gestureDataStore = Session["GestureDataStore"] as Dictionary<int, string> ?? new Dictionary<int, string>();

    // 3. 存储当前训练ID对应的数据(这里的all是你要保存的采集数据)
    gestureDataStore[trainingId] = all;

    // 4. 更新Session中的存储
    Session["GestureDataStore"] = gestureDataStore;

    // 返回成功响应
    return Json(new { name = "Data saved successfully" });
}

备选方案:用静态变量(适合单服务器、无多用户场景)

如果是单用户测试或者不需要用户隔离,可以用静态变量,但要注意线程安全(多个请求同时写入可能出问题):

// 静态字典:全局共享,注意线程安全
private static readonly Dictionary<int, string> _gestureDataStore = new Dictionary<int, string>();
private static readonly object _lockObj = new object(); // 线程锁

[HttpPost]
public ActionResult ReadsSerial(string sintraining)
{
    if (!int.TryParse(sintraining, out int trainingId))
    {
        Console.WriteLine($"Unable to parse '{sintraining}'");
        return BadRequest("Invalid training ID format");
    }

    // 加锁保证线程安全
    lock(_lockObj)
    {
        _gestureDataStore[trainingId] = all;
    }

    return Json(new { name = "Data saved successfully" });
}

3. 新增:批量提交数据到数据库的Action

当用户完成所有数据采集后,需要一个单独的Action来把存储的所有数据合并存入数据库:

[HttpPost]
public ActionResult SaveAllGestures()
{
    // 从Session获取存储的数据
    var gestureDataStore = Session["GestureDataStore"] as Dictionary<int, string>;
    if (gestureDataStore == null || gestureDataStore.Count == 0)
    {
        return BadRequest("No gesture data to save");
    }

    // 这里写合并数据并存入数据库的逻辑
    // 比如遍历字典,把所有数据拼接或批量插入
    foreach(var kvp in gestureDataStore)
    {
        int trainingId = kvp.Key;
        string data = kvp.Value;
        // 执行数据库插入操作:INSERT INTO ... VALUES(trainingId, data)
    }

    // 清空Session中的数据(可选)
    Session.Remove("GestureDataStore");

    return Json(new { status = "success", message = "All data saved to database" });
}

4. 前端代码微调(可选)

前端可以保留原有的ReadsSerial函数,新增一个“提交所有数据”的按钮事件:

// 原有的采集触发函数
function ReadsSerial() {
    $.ajax({
        url: "/Home/ReadsSerial",
        type: 'POST',
        data: { sintraining: gTrained },
        success: function (result) {
            alert(result.name);
        },
        error: function () {
            alert("error");
        }
    });
    return false;
};

// 新增的批量提交函数
function SaveAllData() {
    $.ajax({
        url: "/Home/SaveAllGestures",
        type: 'POST',
        success: function (result) {
            alert(result.message);
        },
        error: function () {
            alert("Failed to save all data");
        }
    });
};

为什么这个方案更优?

  • 扩展性强:新增训练次数不需要修改任何类或判断分支,直接传入新的trainingId即可
  • 数据持久化:利用Session/静态变量解决了HTTP无状态导致的数据丢失问题
  • 代码简洁:去掉了大量重复的类和if分支,维护成本大幅降低

内容的提问来源于stack exchange,提问作者FFLS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:10:20