# LabDataManager.cs ### 主要修改處 * 34 * 72 * 95 - 104 ```csharp= using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using DataSync; using UnityEngine; namespace LabData { public enum SaveType { Json, Csv } public sealed class LabDataManager : ILabDataManager { //private SaveType _saveType = SaveType.Json; [SerializeField] private bool _sendToServer = false; public bool IsClientRunning { get; private set; } private bool _isClientInit = false; private static DataSyncClient _client; private string _saveDataPath; private LabDataScope Scope { get; set; } private Func<string> _userId; private SimpleApplicationLifecycle _applicationLifecycle; private string labDataSavePath => LabTools.DataPath + "/TestData"; // private readonly List<DataWriter> _dataWriters = new List<DataWriter>(); private string _localSaveDataTimeLayout; private ConcurrentQueue<LabDataBase> _dataQueue; private Thread _writeThread; private Dictionary<Type, LabDataWriter> _dataWriterDic; public Action<LabDataBase> GetDataAction { get; set; } /// <summary> /// 数据采集,传入数据,频率,是否循环采集 /// </summary> /// <param name="data"></param> /// <param name="loop"></param> /// <param name="frequency"></param> [Obsolete("功能弃用,新的使用方法请查看Demo")] public void DataCollect(LabDataBase data, bool loop = true, int frequency = 200) { } /// <summary> /// 传入UserID初始化LabDataCollect /// </summary> /// <param name="userId"></param> public void LabDataCollectInit(Func<string> userId) { if (_isClientInit) { return; } #region 初始化本地存储 _localSaveDataTimeLayout = LabTools.GetConfig<LabDataConfig>().LocalSaveDataTimeLayout; _userId = userId; _saveDataPath = LabTools.DataPath + "/Output"; LabTools.CreatSaveDataFolder(_saveDataPath); var userStr = _userId.Invoke().PadLeft(2, '0'); _saveDataPath = string.Join("_", _saveDataPath + "/" + DateTime.Now.ToString(_localSaveDataTimeLayout), userStr); _saveDataPath = LabTools.CreatSaveDataFolder(_saveDataPath); #endregion #region 初始化上传服务 var options = new DataSyncClientOptions() { EndpointAddress = "http://localhost:4000/api/data", ProjectId = LabTools.GetConfig<LabDataConfig>().ProjectId, LogFilePath = labDataSavePath + "/ log.txt" }; //Docker options.EndpointAddress = "http://localhost/api/data"; //server _sendToServer = LabTools.GetConfig<LabDataConfig>().SendToServer; options.EndpointAddress = LabTools.GetConfig<LabDataConfig>().ServerPath; string testStorePath = Path.Combine(LabTools.DataPath, "TestStore"); if (!Directory.Exists(testStorePath)) { Directory.CreateDirectory(testStorePath); } _applicationLifecycle = new SimpleApplicationLifecycle(); _client = new DataSyncClient(new UnityApplicationFolderProvider(testStorePath), _applicationLifecycle, options, _userId); _client.Init(); _isClientInit = true; StartUpload(); #endregion Application.wantsToQuit += () => !IsClientRunning; _dataWriterDic = new Dictionary<Type, LabDataWriter>(); _dataQueue = new ConcurrentQueue<LabDataBase>(); _writeThread = new Thread(Queue2Send); _writeThread.Start(); } async void ILabDataManager.LabDataDispose() { await Task.Run(() => { while(_dataQueue.Count > 0) { Debug.Log(( $"Remain {0} Data to be stored", _dataQueue.Count)); Thread.Sleep(100); } }); foreach (var item in _dataWriterDic) { item.Value.WriterDispose(); } GetDataAction = null; Debug.LogError("LabDataDispose"); StopUpload(); _isClientInit = false; // _dataWriters?.ForEach(p => p.Dispose()); } /// <summary> /// 传输数据 /// </summary> public void SendData(LabDataBase data) { _dataQueue.Enqueue(data); GetDataAction?.Invoke(data); } private void Queue2Send() { while (IsClientRunning) { var dataList = new List<LabDataBase>(); while (_dataQueue.TryDequeue(out var resultData)) { dataList.Add(resultData); } foreach (var d in dataList) { DoOnce(d); } } } private void DoOnce(LabDataBase data) { if (!_isClientInit) { Debug.LogError("LabData未初始化"); return; } DataWriterFunc(data); if (_sendToServer) { Scope.Send(data); } } private void DataWriterFunc(LabDataBase data) { var datatype = data.GetType(); if (!_dataWriterDic.ContainsKey(datatype)) { string dataPath = string.Join("_", _saveDataPath + "/", _userId.Invoke().PadLeft(2, '0'), data.GetType().Name + ".json"); LabTools.CreatData(dataPath); _dataWriterDic.Add(datatype, new LabDataWriter(dataPath)); } _dataWriterDic[datatype].WriteData(data); } private void StartUpload() { if (IsClientRunning) { return; } Debug.Log("开始"); _applicationLifecycle.OnStarted(EventArgs.Empty); Scope = _client.CreateNewScope(); Scope.StartScope(); IsClientRunning = true; } private void StopUpload() { if (!IsClientRunning) { return; } Debug.Log("停止"); Scope.StopScope(); Scope.Dispose(); _applicationLifecycle.OnStopping(ApplicationStoppingEventArgs.Empty); IsClientRunning = false; } } public class LabDataWriter { private readonly FileStream _fs; private readonly StreamWriter _sw; public LabDataWriter(string path) { _fs = new FileStream(path, FileMode.Append, FileAccess.Write); _sw = new StreamWriter(_fs); } public void WriteData(LabDataBase data) { _sw.WriteLine(data.ToJson()); } public void WriterDispose() { _sw.Flush(); _fs.Close(); } } } ```