using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace CeShi
{
public class IntelligentTaskProcessing
{
/// <summary>
/// 队列中允许存储最大数量
/// </summary>
public int Queue_MaxCount = 50;
/// <summary>
/// 队列中数量小于这个数值从数据库取数据
/// </summary>
public int Queue_MinCount = 15;
/// <summary>
/// 并行运行任务数量
/// </summary>
public int MaxRunCount = 1;
/// <summary>
/// 目前运行处理个数
/// </summary>
private int _RunCount = 0;
/// <summary>
/// 一个任务处理完成后回调
/// </summary>
public Action<DataModel> OnSuccess_CallBack { get; set; }
/// <summary>
/// 具体任务的处理
/// </summary>
public Action<DataModel> OnDisposeOneOrder { get; set; }
/// <summary>
/// 获取数据,并且自动添加到任务中
/// </summary>
public Func<List<Orders>> OnGetOrders { get; set; }
/// <summary>
/// 开始处理任务-只允许调用一次
/// </summary>
public void StateDispostData()
{
StartGetData();
StartDisposeTask();
}
/// <summary>
/// 设置多线程工作状态
/// </summary>
/// <param name="queueMin">队列数量最小 获取数据</param>
/// <param name="queueMax">队列数量最大 停止获取数据</param>
/// <param name="runCount">队列服务运行数量</param>
public void Set(int queueMin = 20, int queueMax = 50, int runCount = 5)
{
Queue_MaxCount=queueMax;
Queue_MinCount=queueMin;
MaxRunCount=runCount;
}
private ConcurrentQueue<Mission> _allTask = new ConcurrentQueue<Mission>();
private Task TaskDetail(Mission mission)
{
return new Task(() =>
{
try
{
mission._Data.time2=DateTime.Now;
OnDisposeOneOrder?.Invoke(mission._Data);
mission._Data.time3=DateTime.Now;
OnSuccess_CallBack?.Invoke(mission._Data);
}
catch (Exception ex)
{
throw ex;
}
finally
{
Interlocked.Decrement(ref _RunCount);
}
});
}
private void Add_Data(Orders order)
{
if (_allTask.Count(x => x._Data._Data.Id==order.Id)<=0)//判断是否存在
{
Mission task = new Mission();
var data = new DataModel();
data._Data=order;
task._Data = data;
task._Data.time1=DateTime.Now;
task._Task=TaskDetail(task);
_allTask.Enqueue(task);
}
}
private void StartGetData()
{
Task.Factory.StartNew(() =>
{
while (true)
{
var sleepTime = 5000;
if (_allTask.Count>Queue_MaxCount)//判断大于最大队列数量,暂时停止获取添加数据
{
sleepTime=60000;
}
else if (_allTask.Count<=Queue_MinCount)
{
var orders = OnGetOrders?.Invoke();
if (orders!=null&&orders.Count>0)
{
orders.ForEach(x =>
{
Add_Data(x);
});
if (orders.Count>=10)
{
sleepTime = 2000;
}
}
}
Thread.Sleep(sleepTime);
}
});
}
private void StartDisposeTask()
{
Task.Factory.StartNew(() =>
{
while (true)
{
if (_allTask.Count>0&&_RunCount<MaxRunCount)
{
var canCount = MaxRunCount-_RunCount;
for (int i = 0; i <canCount; i++)
{
if (_allTask.TryDequeue(out Mission task))
{
task._Task.Start();
Interlocked.Increment(ref _RunCount);
}
}
}
else
{
Thread.Sleep(1000);
}
}
});
}
}
public class Mission
{
public DataModel _Data { get; set; }
public Task _Task { get; set; }
public TaskCreationOptions _Task_Options = new TaskCreationOptions();
}
/// <summary>
/// 用于存放数据模型
/// </summary>
public class DataModel
{
/// <summary>
/// 处理数据
/// </summary>
public Orders _Data { get; set; }
public TimeSpan time { get; set; }
public DateTime time1 { get; set; }
public DateTime time2 { get; set; }
public DateTime time3 { get; set; }
}
}
调用方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;
namespace TestIntellig
{
internal class Program
{
public static IntelligentTaskProcessing _interll = new IntelligentTaskProcessing();
static void Main(string[] args)
{
Initinal();
while (true)
{
Console.ReadLine();
}
}
public static void Initinal()
{
_interll.OnGetOrders= () =>
{
List<Orders> listorders = RandomGetOrders();
return listorders;
};
_interll.OnDisposeOneOrder=a =>
{
var randomTime = random.Next(2000, 8000);
Console.WriteLine($"处理任务{a._Data.Id} 需要处理{randomTime}毫秒");
var item = a._Data;
var start = DateTime.Now;
Thread.Sleep(randomTime);
a.time=DateTime.Now.Subtract(start);
};
_interll.OnSuccess_CallBack+=a =>
{
var obj = JsonConvert.SerializeObject(new { a._Data.Id, needtime = a.time, alltime = a.time3- a.time1 });
Console.WriteLine(obj);
};
_interll.StateDispostData();
}
public static Random random = new Random();
public static List<Orders> RandomGetOrders()
{
List<Orders> orders = new List<Orders>();
for (int i = 0; i < random.Next(20, 50); i++)
{
orders.Add(new Orders() { Id=random.Next().ToString() });
}
return orders;
}
}
}