diff --git a/KsatSupplymentLibrary/App.config b/KsatSupplymentLibrary/App.config
new file mode 100644
index 0000000..16a26b2
--- /dev/null
+++ b/KsatSupplymentLibrary/App.config
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KsatSupplymentLibrary/KsatSupplymentLibrary.csproj b/KsatSupplymentLibrary/KsatSupplymentLibrary.csproj
new file mode 100644
index 0000000..3d326cc
--- /dev/null
+++ b/KsatSupplymentLibrary/KsatSupplymentLibrary.csproj
@@ -0,0 +1,96 @@
+
+
+
+
+
+ Debug
+ AnyCPU
+ {3C90349C-2148-4D79-9881-7B3474EA8AF7}
+ Library
+ Properties
+ Ksat.Supplyment.Library
+ KsatSupplymentLibrary
+ v4.5
+ 512
+ true
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll
+
+
+ ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll
+
+
+ ..\packages\SQLite.CodeFirst.1.7.0.34\lib\net45\SQLite.CodeFirst.dll
+
+
+
+
+
+
+ ..\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.115.5\lib\net45\System.Data.SQLite.dll
+
+
+ ..\packages\System.Data.SQLite.EF6.1.0.115.5\lib\net45\System.Data.SQLite.EF6.dll
+
+
+ ..\packages\System.Data.SQLite.Linq.1.0.115.5\lib\net45\System.Data.SQLite.Linq.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KsatSupplymentLibrary/Model/CodeFirstDbContext.cs b/KsatSupplymentLibrary/Model/CodeFirstDbContext.cs
new file mode 100644
index 0000000..9a7cada
--- /dev/null
+++ b/KsatSupplymentLibrary/Model/CodeFirstDbContext.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Data.Entity;
+using System.Linq;
+
+namespace Ksat.Supplyment.Library.Model
+{
+ public class CodeFirstDbContext : DbContext
+ {
+ //您的上下文已配置为从您的应用程序的配置文件(App.config 或 Web.config)
+ //使用“CodeFirstDbContext”连接字符串。默认情况下,此连接字符串针对您的 LocalDb 实例上的
+ //“Ksat.Supplyment.Library.Model.CodeFirstDbContext”数据库。
+ //
+ //如果您想要针对其他数据库和/或数据库提供程序,请在应用程序配置文件中修改“CodeFirstDbContext”
+ //连接字符串。
+ public CodeFirstDbContext() : base(@"name = sqlite")
+ {
+ }
+
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+ modelBuilder.Entity().ToTable("UploadCaches").HasKey(p => p.Id);
+ modelBuilder.Entity().ToTable("UploadCancels").HasKey(p => p.Id);
+ modelBuilder.Entity().ToTable("UploadFinishs").HasKey(p => p.Id);
+ Database.SetInitializer(new SQLite.CodeFirst.SqliteCreateDatabaseIfNotExists(modelBuilder));
+ }
+
+ //为您要在模型中包含的每种实体类型都添加 DbSet。有关配置和使用 Code First 模型
+ //的详细信息,请参阅 https://blog.csdn.net/wucdsg/article/details/78895366
+ public virtual DbSet UploadCaches { get; set; }
+ public virtual DbSet UploadCancels { get; set; }
+ public virtual DbSet UploadFinishs { get; set; }
+ }
+
+ //public class MyEntity
+ //{
+ // public int Id { get; set; }
+ // public string Name { get; set; }
+ //}
+}
\ No newline at end of file
diff --git a/KsatSupplymentLibrary/Model/Uploader/UploadCache.cs b/KsatSupplymentLibrary/Model/Uploader/UploadCache.cs
new file mode 100644
index 0000000..ad6172f
--- /dev/null
+++ b/KsatSupplymentLibrary/Model/Uploader/UploadCache.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Ksat.Supplyment.Library.Model.Uploader
+{
+ public class UploadCache
+ {
+ [Key]
+ public int Id { get; set; }
+
+ ///
+ /// 属于哪个上传任务
+ ///
+ [Required]
+ public string UploaderID { get; set; }
+
+ [Required]
+ public DateTime CreateAt { get; set; }
+
+ ///
+ /// 最后一次上传时间
+ ///
+ public DateTime RetryAt { get; set; }
+
+ ///
+ /// 尝试次数
+ ///
+ public int RetryCount { get; set; }
+
+ ///
+ /// 错误信息
+ ///
+ public string ErrorInfo { get; set; }
+
+ ///
+ /// 上传相关数据
+ ///
+ public string RequestData { get; set; }
+ }
+}
diff --git a/KsatSupplymentLibrary/Model/Uploader/UploadCancel.cs b/KsatSupplymentLibrary/Model/Uploader/UploadCancel.cs
new file mode 100644
index 0000000..683587c
--- /dev/null
+++ b/KsatSupplymentLibrary/Model/Uploader/UploadCancel.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Ksat.Supplyment.Library.Model.Uploader
+{
+ public class UploadCancel
+ {
+ [Key]
+ public int Id { get; set; }
+
+ ///
+ /// 属于哪个上传任务
+ ///
+ [Required]
+ public string UploaderID { get; set; }
+
+ [Required]
+ public DateTime CreateAt { get; set; }
+
+ ///
+ /// 最后一次上传时间
+ ///
+ public DateTime RetryAt { get; set; }
+
+ ///
+ /// 错误信息
+ ///
+ public string ErrorInfo { get; set; }
+
+ ///
+ /// 尝试次数
+ ///
+ public int RetryCount { get; set; }
+
+ ///
+ /// 上传相关数据
+ ///
+ public string RequestData { get; set; }
+ }
+}
diff --git a/KsatSupplymentLibrary/Model/Uploader/UploadFinish.cs b/KsatSupplymentLibrary/Model/Uploader/UploadFinish.cs
new file mode 100644
index 0000000..0425418
--- /dev/null
+++ b/KsatSupplymentLibrary/Model/Uploader/UploadFinish.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Ksat.Supplyment.Library.Model.Uploader
+{
+ public class UploadFinish
+ {
+ [Key]
+ public int Id { get; set; }
+
+ ///
+ /// 属于哪个上传任务
+ ///
+ [Required]
+ public string UploaderID { get; set; }
+
+ [Required]
+ public DateTime CreateAt { get; set; }
+
+ ///
+ /// 最后一次上传时间
+ ///
+ public DateTime RetryAt { get; set; }
+
+ ///
+ /// 尝试次数
+ ///
+ public int RetryCount { get; set; }
+
+ ///
+ /// 上传相关数据
+ ///
+ public string RequestData { get; set; }
+ }
+}
diff --git a/KsatSupplymentLibrary/Model/Uploader/UploadModel.cs b/KsatSupplymentLibrary/Model/Uploader/UploadModel.cs
new file mode 100644
index 0000000..3128fea
--- /dev/null
+++ b/KsatSupplymentLibrary/Model/Uploader/UploadModel.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Ksat.Supplyment.Library.Model.Uploader
+{
+ public class UploadModel
+ {
+ public DateTime CreateAt;
+
+ ///
+ /// 最后一次上传时间
+ ///
+ public DateTime RetryAt;
+
+ ///
+ /// 尝试次数
+ ///
+ public int RetryCount;
+
+ ///
+ /// 错误信息
+ ///
+ public string ErrorInfo;
+
+ public T Request;
+ }
+}
diff --git a/KsatSupplymentLibrary/Properties/AssemblyInfo.cs b/KsatSupplymentLibrary/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..289b509
--- /dev/null
+++ b/KsatSupplymentLibrary/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("KsatSupplymentLibrary")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("KsatSupplymentLibrary")]
+[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("3c90349c-2148-4d79-9881-7b3474ea8af7")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/KsatSupplymentLibrary/Uploader/IUploaderOperator.cs b/KsatSupplymentLibrary/Uploader/IUploaderOperator.cs
new file mode 100644
index 0000000..932935f
--- /dev/null
+++ b/KsatSupplymentLibrary/Uploader/IUploaderOperator.cs
@@ -0,0 +1,39 @@
+using Ksat.Supplyment.Library.Model.Uploader;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Ksat.Supplyment.Library.Uploader
+{
+
+ public interface IUploaderOperator
+ {
+
+ ///
+ /// 上传数据
+ ///
+ IUploaderRequest UploadData(T data);
+
+
+
+ T ConvertCacheToRequest(string cache);
+ string ConvertRequestToCachel(T requestData);
+
+ ///
+ /// 任务开始前,判断任务是否要开始
+ ///
+ ///
+ ///
+ ///
+ bool ShouldStartRequest(UploadModel requestModel, out string cancelReason);
+
+ ///
+ /// 任务失败以后,判断是否需要重试
+ ///
+ ///
+ ///
+ ///
+ bool ShouldRetryRequest(UploadModel requestModel, out string cancelReason);
+ }
+}
\ No newline at end of file
diff --git a/KsatSupplymentLibrary/Uploader/IUploaderRequest.cs b/KsatSupplymentLibrary/Uploader/IUploaderRequest.cs
new file mode 100644
index 0000000..0757e98
--- /dev/null
+++ b/KsatSupplymentLibrary/Uploader/IUploaderRequest.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Ksat.Supplyment.Library.Model.Uploader;
+
+namespace Ksat.Supplyment.Library.Uploader
+{
+ public delegate void UploadFinishHandler(object sender, bool success, string reason) ;
+
+ public interface IUploaderRequest
+ {
+ ///
+ /// 请求数据
+ ///
+ T RequestData { get; set; }
+
+ ///
+ /// 开始上传任务
+ ///
+ void Start();
+
+ ///
+ /// 停止上传任务
+ ///
+ void Cancel();
+
+ ///
+ /// 上传完成事件
+ ///
+ event UploadFinishHandler UploadFinish;
+ }
+}
\ No newline at end of file
diff --git a/KsatSupplymentLibrary/Uploader/Uploader.cs b/KsatSupplymentLibrary/Uploader/Uploader.cs
new file mode 100644
index 0000000..ddbb11c
--- /dev/null
+++ b/KsatSupplymentLibrary/Uploader/Uploader.cs
@@ -0,0 +1,412 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using Ksat.Supplyment.Library.Model.Uploader;
+using Ksat.Supplyment.Library.Model;
+
+namespace Ksat.Supplyment.Library.Uploader
+{
+ public class Uploader : IDisposable
+ {
+ ///
+ /// 上传操作执行者
+ ///
+ internal IUploaderOperator mOperator;
+
+ ///
+ /// 上传数据队列
+ ///
+ private readonly ConcurrentQueue> mDatas = new ConcurrentQueue>();
+
+ ///
+ /// 交换数据队列
+ ///
+ private readonly ConcurrentQueue> mSwapDatas = new ConcurrentQueue>();
+
+ ///
+ /// 上传请求
+ ///
+ private readonly LinkedList, UploadModel>> mRequests = new LinkedList, UploadModel>>();
+
+ private readonly System.Threading.Thread mDatasWorkerThread;
+
+ ///
+ /// 最大队列长度
+ ///
+ public int MaxOperatingQueueSize = 5;
+
+ ///
+ /// 同时上传的数量
+ ///
+ public int MaxCocurrentTaskCount = 2;
+
+ private int mIsCanceled = 0;
+
+ ///
+ /// 任务唯一标识,与数据库中UploaderID对应
+ ///
+ private string mTaskIdentify;
+
+ private Timer mSwapClearTimer;
+
+
+ public Uploader(string ID, IUploaderOperator op)
+ {
+ if (op == null)
+ throw new System.ArgumentNullException();
+ this.mTaskIdentify = ID;
+ this.mOperator = op;
+ //sLog = LoggerFactory.ForContext("Uploader:" + this.mTaskIdentify);
+ mDatasWorkerThread = new System.Threading.Thread(uploadWorker)
+ {
+ Name = "upload worker",
+ IsBackground = true
+ };
+ mDatasWorkerThread.Start();
+
+ mSwapClearTimer = new Timer((x) =>
+ {
+ var toDBs = new List>();
+
+ UploadModel d;
+ while (mSwapDatas.TryDequeue(out d))
+ {
+ toDBs.Add(d);
+ }
+ if (toDBs.Count != 0)
+ cacheRequest(toDBs);
+ }, null, 4000, 4000);
+ }
+
+ public void Dispose()
+ {
+ Interlocked.Exchange(ref mIsCanceled, 1);
+ try
+ {
+ mSwapClearTimer.Dispose();
+ mDatasWorkerThread.Abort();
+
+ List> toCache = new List>();
+
+ ///取消当前上传中任务,
+ lock (mRequests)
+ {
+ mRequests.ToList().ForEach((r) =>
+ {
+ r.Item1.UploadFinish -= Req_OnRequestFinished;
+ r.Item1.Cancel();
+ r.Item2.ErrorInfo = "上传程序中止,任务cancel";
+ toCache.Add(r.Item2);
+ });
+ }
+ mDatas.ToList().ForEach((d) => toCache.Add(d));
+ mSwapDatas.ToList().ForEach((d) => toCache.Add(d));
+ cacheRequest(toCache);
+ }
+ catch
+ {
+ }
+ }
+
+ ///
+ /// 加入到上传任务队列
+ ///
+ ///
+ ///
+ private void enqueRequest(TReq req, UploadModel requestModel) where TReq : IUploaderRequest
+ {
+ req.UploadFinish += Req_OnRequestFinished;
+ lock (mRequests)
+ {
+ mRequests.AddLast(new Tuple, UploadModel>(req, requestModel));
+ }
+ }
+
+ ///
+ /// 从上传任务队列中移除
+ ///
+ ///
+ ///
+ private UploadModel dequeRequest(TReq req) where TReq : IUploaderRequest
+ {
+ req.UploadFinish -= Req_OnRequestFinished;
+ UploadModel reqModel = null;
+ lock (mRequests)
+ {
+ var found = mRequests.FirstOrDefault((x) => x.Item1 == req as IUploaderRequest);
+ if (found != null)
+ {
+ reqModel = found.Item2;
+ mRequests.Remove(found);
+ }
+ }
+ return reqModel;
+ }
+
+ ///
+ /// 任务完成回调
+ ///
+ ///
+ ///
+ private void Req_OnRequestFinished(object sender, bool success, string reason)
+ {
+ var request = sender as IUploaderRequest;
+ var x = (request.RequestData);
+ var reqModel = dequeRequest(request);
+
+ if (reqModel == null)
+ {
+ //sLog.Formf($"no request found:{request.RequestData}");
+ return;
+ }
+ reqModel.ErrorInfo = reason;
+
+
+ //sLog.Formf($"{reqModel.Request} finished:{success}");
+ string cancelRetryReason = null;
+ if (success)
+ using (var db = new CodeFirstDbContext())
+ {
+ db.UploadFinishs.Add(new UploadFinish
+ {
+ CreateAt = reqModel.CreateAt,
+ RetryAt = reqModel.RetryAt,
+ RetryCount = reqModel.RetryCount,
+ RequestData = mOperator.ConvertRequestToCachel(reqModel.Request),
+ UploaderID = mTaskIdentify
+ });
+ db.SaveChanges();
+
+ }
+ else if (mOperator.ShouldRetryRequest(reqModel, out cancelRetryReason))
+ {
+
+ if (mDatas.Count >= MaxOperatingQueueSize)
+ {
+ mSwapDatas.Enqueue(reqModel);
+ }
+ else
+ {
+ mDatas.Enqueue(reqModel);
+ }
+ }
+ else
+ {
+ using (var db = new CodeFirstDbContext())
+ {
+ db.UploadCancels.Add(new UploadCancel
+ {
+ CreateAt = reqModel.CreateAt,
+ RetryAt = reqModel.RetryAt,
+ RetryCount = reqModel.RetryCount,
+ RequestData = mOperator.ConvertRequestToCachel(reqModel.Request),
+ ErrorInfo = "Task cancel Retry:" + cancelRetryReason ?? "No Reason",
+ UploaderID = mTaskIdentify
+ });;
+ db.SaveChanges();
+ }
+ }
+
+ Console.WriteLine($"{DateTime.UtcNow.ToString("mm:ss.fff")} task {x} result:{success}");
+ //throw new NotImplementedException();
+ }
+
+ ///
+ /// 上传worker
+ ///
+ private void uploadWorker()
+ {
+ while (!Interlocked.Equals(mIsCanceled, 1))
+ {
+ int reqCount;
+ lock (mRequests)
+ reqCount = mRequests.Count;
+ if (reqCount >= MaxCocurrentTaskCount)
+ {
+ System.Threading.Thread.Sleep(10);
+ Console.WriteLine($"{DateTime.UtcNow.ToString("mm:ss.fff")} task exceed {MaxCocurrentTaskCount}, waiting");
+ continue;
+ }
+ int newRequestCount = MaxCocurrentTaskCount - reqCount;
+
+ //只尝试加载一次cache
+ bool hasGotCache = false;
+ for (int i = 0; i < newRequestCount;)
+ {
+ UploadModel d;
+ if (mDatas.TryDequeue(out d))
+ {
+ string donotStartReason;
+ if (!mOperator.ShouldStartRequest(d, out donotStartReason))
+ {
+ using (var db = new CodeFirstDbContext())
+ {
+ db.UploadCancels.Add(new UploadCancel
+ {
+ CreateAt = d.CreateAt,
+ RetryAt = d.RetryAt,
+ RetryCount = d.RetryCount,
+ RequestData = mOperator.ConvertRequestToCachel(d.Request),
+ ErrorInfo = "Task cancel Start:" + donotStartReason ?? "No Reason",
+ UploaderID = mTaskIdentify
+ }); ;
+ db.SaveChanges();
+ }
+ continue;
+ }
+ d.RetryAt = DateTime.Now;
+ d.RetryCount++;
+ var req = mOperator.UploadData(d.Request);
+ enqueRequest(req, d);
+ ThreadPool.QueueUserWorkItem(new WaitCallback((o) => req.Start()));
+ //new System.Threading.Thread(req.Start).Start();
+ //req.Start();
+ i++;
+ continue;
+ }
+ else if (!hasGotCache)
+ {
+ hasGotCache = true;
+ var caches = getCaches(MaxOperatingQueueSize);
+ if (caches.Count == 0)
+ {
+ //cache也没有任务了
+ break;
+ }
+ caches.ForEach((t) => { mDatas.Enqueue(t); });
+ continue;
+ }
+ }
+ }
+ }
+
+ private void cacheRequest(List datas)
+ {
+ using (var db = new CodeFirstDbContext())
+ {
+ //sLog.Formf($"cache requests,{datas.Count()}");
+ var caches = datas.Select((data) =>
+ new UploadCache
+ {
+ UploaderID = mTaskIdentify,
+ CreateAt = DateTime.Now,
+ RetryAt = new DateTime(1970, 1, 1),
+ RetryCount = 0,
+ ErrorInfo = "",
+ RequestData = mOperator.ConvertRequestToCachel(data)
+ }
+ );
+ db.UploadCaches.AddRange(caches);
+ db.SaveChanges();
+ }
+ }
+
+ ///
+ /// 缓存请求数据到数据库
+ ///
+ ///
+ private void cacheRequest(List> datas)
+ {
+ //sLog.Formf($"cache requests count,{datas.Count()}");
+ using (var db = new CodeFirstDbContext())
+ {
+ var caches = datas.Select((data) =>
+ new UploadCache
+ {
+ UploaderID = mTaskIdentify,
+ CreateAt = data.CreateAt,
+ RetryAt = data.RetryAt,
+ RetryCount = data.RetryCount,
+ ErrorInfo = data.ErrorInfo,
+ RequestData = mOperator.ConvertRequestToCachel(data.Request)
+ }
+ );
+ db.UploadCaches.AddRange(caches);
+ db.SaveChanges();
+ }
+ }
+
+ ///
+ /// 从数据库中提取指定数量的请求数据
+ ///
+ ///
+ ///
+ private List> getCaches(int number)
+ {
+ var ret = new List>();
+ var toGet = number;
+ UploadModel model;
+
+ while (toGet > 0 && mSwapDatas.TryDequeue(out model))
+ {
+ ret.Add(model);
+ toGet--;
+ }
+
+ using (var db = new CodeFirstDbContext())
+ {
+ var caches = from c in db.UploadCaches
+ orderby c.RetryAt ascending
+ where c.UploaderID == this.mTaskIdentify
+ select c;
+ var x = caches.Take(toGet).ToList();
+ //从数据库中移除
+ db.UploadCaches.RemoveRange(x);
+ db.SaveChanges();
+ var modelsFromDB = x.Select((data) =>
+ new UploadModel
+ {
+ CreateAt = data.CreateAt,
+ RetryAt = data.RetryAt,
+ RetryCount = data.RetryCount,
+ ErrorInfo = data.ErrorInfo,
+ Request = mOperator.ConvertCacheToRequest(data.RequestData)
+ }
+ ).ToList();
+
+ ret.AddRange(modelsFromDB);
+ }
+
+ //if (ret.Count() != 0)
+ //sLog.Formf($"get {number} cache return {ret.Count()}");
+ return ret;
+ }
+
+ ///
+ /// 添加上传请求
+ ///
+ public void AddUploadRequest(T data)
+ {
+ if (!Interlocked.Equals(mIsCanceled, 1))
+ {
+
+ var requestData = new UploadModel
+ {
+ CreateAt = DateTime.Now,
+ RetryAt = new DateTime(1970, 1, 1),
+ RetryCount = 0,
+ ErrorInfo = "",
+ Request = data
+ };
+ if (mDatas.Count >= MaxOperatingQueueSize)
+ {
+ //sLog.Formf($"add request to swap,{data}");
+ mSwapDatas.Enqueue(requestData);
+ }
+ else
+ {
+ //sLog.Formf($"add request to queue,{data}");
+ mDatas.Enqueue(requestData);
+ }
+ }
+ else
+ {
+ //sLog.Formf("task canceled");
+ cacheRequest(new List() { data });
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/KsatSupplymentLibrary/flow.drawio b/KsatSupplymentLibrary/flow.drawio
new file mode 100644
index 0000000..2616b23
--- /dev/null
+++ b/KsatSupplymentLibrary/flow.drawio
@@ -0,0 +1 @@
+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
\ No newline at end of file
diff --git a/KsatSupplymentLibrary/packages.config b/KsatSupplymentLibrary/packages.config
new file mode 100644
index 0000000..b82eda8
--- /dev/null
+++ b/KsatSupplymentLibrary/packages.config
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/S3Demo.sln b/S3Demo.sln
index 0bbe9bd..97d3ebd 100644
--- a/S3Demo.sln
+++ b/S3Demo.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.31702.278
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "S3Demo", "S3Demo\S3Demo.csproj", "{10785A7F-B71E-4576-BD28-3979CD9A005C}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KsatSupplymentLibrary", "KsatSupplymentLibrary\KsatSupplymentLibrary.csproj", "{3C90349C-2148-4D79-9881-7B3474EA8AF7}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
{10785A7F-B71E-4576-BD28-3979CD9A005C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10785A7F-B71E-4576-BD28-3979CD9A005C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10785A7F-B71E-4576-BD28-3979CD9A005C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3C90349C-2148-4D79-9881-7B3474EA8AF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3C90349C-2148-4D79-9881-7B3474EA8AF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3C90349C-2148-4D79-9881-7B3474EA8AF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3C90349C-2148-4D79-9881-7B3474EA8AF7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/S3Demo/App.config b/S3Demo/App.config
index 8e15646..d8c2c6c 100644
--- a/S3Demo/App.config
+++ b/S3Demo/App.config
@@ -1,6 +1,25 @@
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/S3Demo/Run.cs b/S3Demo/Run.cs
index 0d20f3f..fe3a130 100644
--- a/S3Demo/Run.cs
+++ b/S3Demo/Run.cs
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO;
+using Ksat.Supplyment.Library.Model;
namespace S3Demo
{
@@ -45,8 +46,27 @@ namespace S3Demo
private static string[] paths = { @"D:\ClientDir" };
private static string suffix = "*.png";
private static bool incsubdir = true;
+
public static void Main()
{
+ /// 写入数据库操作
+ //using (var dev = new CodeFirstDbContext())
+ //{
+ // dev.UploadCaches.Add(new Ksat.Supplyment.Library.Model.Uploader.UploadCache() {
+ // Id = 1,
+ // UploaderID = "02",
+ // CreateAt = DateTime.Now.AddHours(-1),
+ // RetryAt = DateTime.Now,
+ // RetryCount = 1,
+ // ErrorInfo = "null",
+ // RequestData = "testInfo"
+ // });
+ // var i = dev.SaveChanges();
+ // Console.WriteLine(i);
+ //}
+
+
+
try
{
//FileModel.onFileChange(paths, suffix, true);
@@ -70,7 +90,7 @@ namespace S3Demo
watch.EnableRaisingEvents = true;
}
- #region S3相关测试
+ #region S3相关测试
/*
//creating Bucket
//await CreateBucket.CreatingBucket("minio/bu29", credentials, conf);
@@ -116,9 +136,9 @@ namespace S3Demo
//await new AmazonS3Client(credentials, conf).DeleteBucketAsync(bucketName);
//Console.WriteLine("delete bucket " + bucketName);
*/
- #endregion
+ #endregion
- #region 路径解析
+ #region 路径解析
//string fullpath = @"C:\line01\AOI\20211129\120955851P107CN14T00001OK.png";
//string fileName = System.IO.Path.GetFileNameWithoutExtension(fullpath);
//string date = System.IO.Path.GetDirectoryName(fullpath).Split('\\')[3];
@@ -137,7 +157,7 @@ namespace S3Demo
//Console.WriteLine("datetime: " + datetime);
//string dt = DateTime.ParseExact(datetime, "yyyyMMddHHmmssfff", System.Globalization.CultureInfo.CurrentCulture).ToString("yyyy-MM-dd HH:mm:ss:fff");
//Console.WriteLine("format: " + dt);
- #endregion
+ #endregion
}
catch (Exception ex)
{
diff --git a/S3Demo/S3Demo.csproj b/S3Demo/S3Demo.csproj
index e201e7e..3175730 100644
--- a/S3Demo/S3Demo.csproj
+++ b/S3Demo/S3Demo.csproj
@@ -1,5 +1,6 @@
+
Debug
@@ -11,6 +12,8 @@
v4.5
512
true
+
+
preview
@@ -41,8 +44,27 @@
..\packages\AWSSDK.S3.3.7.5\lib\net45\AWSSDK.S3.dll
+
+ ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll
+
+
+ ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll
+
+
+ ..\packages\SQLite.CodeFirst.1.7.0.34\lib\net45\SQLite.CodeFirst.dll
+
+
+
+ ..\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.115.5\lib\net45\System.Data.SQLite.dll
+
+
+ ..\packages\System.Data.SQLite.EF6.1.0.115.5\lib\net45\System.Data.SQLite.EF6.dll
+
+
+ ..\packages\System.Data.SQLite.Linq.1.0.115.5\lib\net45\System.Data.SQLite.Linq.dll
+
@@ -67,5 +89,24 @@
+
+
+ {3c90349c-2148-4d79-9881-7b3474ea8af7}
+ KsatSupplymentLibrary
+
+
+
+
+
+
+
+ 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/S3Demo/packages.config b/S3Demo/packages.config
index 825e538..1bb408c 100644
--- a/S3Demo/packages.config
+++ b/S3Demo/packages.config
@@ -2,4 +2,11 @@
+
+
+
+
+
+
+
\ No newline at end of file