如何用同一类存储函数多次运行产生的数据
优化方案:解决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
相关产品推荐
相关产品推荐

