项目中,当需要使用多线程时,习惯用Task 或者Thread去开启线程,当需要响应速度时,Task总是不那么让人满意。
建立任务池,多个线程在循环执行,当有任务过来时,就立即使用空闲的线程去执行任务,以达到快速响应的效果。
以下是任务池的设计代码:
使用中有问题,或有优化的地方,可以在评论区提出,感谢!
————————————————————————————————————————
可以直接引用Nuget包 LS.Helper 即可使用 或直接使用源码也可以(往下拉)
使用示例:
///
/// 用Thread运行方法
/// 一般用于整个生命周期的线程
///
///
///
public static Thread RunByThread(Action action)
{
Thread _t = new Thread(() => { action.Invoke(); }) { IsBackground = true };
_t.Start();
return _t;
}
///
/// 使用任务池运行方法
/// 一般用于临时运行或者周期性运行的方法
///
///
///
public static BaseResult RunByActionPool(Action action)
{
return ACPool.AddAction(action);
}
private static readonly object locker = new object();
private static ActionPool _acPool;
///
/// 任务池对象
///
public static ActionPool ACPool
{
get
{
lock (locker)
{
if (_acPool == null)
{
_acPool = new ActionPool();
_acPool.InitThread();
}
return _acPool;
}
}
}
✍更新说明
—–2023年09月11日————————————————————————————————————–
1.增加Waiting状态,当SetAction()时,状态立即变更为Waiting
2.SetAction()前再次对线程状态做确认,确保数据稳定
下面是实现源码:
///
/// 任务池
/// 目前支持无返回值的方法执行
///
public class ActionPool
{
///
/// 线程总数
///
public int PoolCount = 50;
///
/// 待执行的方法集合
///
private ConcurrentQueue actions = new ConcurrentQueue();
///
/// 标识是否运行任务池
///
private bool isRunThread = false;
///
/// 线程列表
///
private List threads = new List();
///
/// 轮询线程
///
private Thread _thread;
///
/// 日志信息输出 委托
///
public delegate void DelegateLog(string log);
///
/// 日志信息输出
///
public event DelegateLog SendLog;
///
/// 任务池
///
public ActionPool()
{
}
///
/// 任务池初始化
///
/// 线程总数
public void InitThread(int poolCount = 50)
{
try
{
PoolCount = poolCount;
if (!isRunThread)
{
服务器托管网isRunThread = true;
threads = new List();
for (int i = 0; i
/// 当有任务进来时,选择空闲的线程去执行任务
///
private void Execute()
{
while (isRunThread)
{
try
{
if (actions.Count > 0)
{
var index = threads.FindIndex(x => x.IsReady());
if (index >= 0)
{
var t = threads[index];
//再次确认是否可以添加任务进来
if (t.IsReady())
{
if (actions.TryDequeue(out Action action))
t.SetAction(action);
}
}
}
}
catch (Exception ex)
{ }
Thread.Sleep(10);
}
}
///
/// 添加执行方法到任务池
///
///
///
public BaseResult AddAction(Action action)
{
try
{
if (action == null)
return new BaseResult(false, "Action 不能为Null");
actions.Enqueue(action);
return BaseResult.Successed;
}
catch (Exception ex)
{
return new BaseResult(false, ex.ToString());
}
}
///
/// 结束线程池
///
public void Stop()
{
try
{
isRunThread = false;
if (threads.Count > 0)
{
foreach (var t in threads)
{
try
{
t.Stop();
}
catch (Exception ex) { }
}
}
_thread?.Join();
}
catch (Exception ex)
{
}
}
}
///
/// 工作线程对象
///
public class ActionThread
{
///
/// 线程对象
///
private Thread _thread;
///
/// 工作状态
///
public ActionState ActionStatus;
///
/// 需要执行的方法
///
private Action _action;
///
/// 标识是否运行线程
///
private bool isRunThread = false;
///
/// 循环线程的睡眠时间
///
private int _sleeptime = 500;
///
/// 锁对象
///
private static readonly object _lock = new object();
///
/// 日志信息输出 委托
///
public delegate void DelegateLog(string log);
///
/// 日志信息输出
///
public event DelegateLog SendLog;
public ActionThread(int sleeptime = 500)
{
ActionStatus = ActionState.Init;
_sleeptime = sleeptime;
_action = null;
isRunThread = true;
_thread = new Thread(Execute) { IsBackground = true };
_thread.Start();
ActionStatus = ActionState.Ready;
}
///
/// 判断线程是否有空闲
///
///
public bool IsReady()
{
return (ActionStatus == ActionState.Ready && _action == null);
}
///
/// 执行任务--循环方法
///
public void Execute()
{
while (isRunThread)
{
try
{
lock (_lock)
{
if ((ActionStatus == ActionState.Ready|| ActionStatus==ActionState.Waiting) && _action != null)
{
ActionStatus = ActionState.Working;
DateTime begin = DateTime.Now;
SendLog?.Invoke($"ID[{_thread.ManagedThreadId}] 开始执行Action[{_action.Method.Name}]");
//_action.Invoke();
var res = _action.BeginInvoke((ar) =>
{
服务器托管网 _action = null;
ActionStatus = ActionState.Ready;
}, null);
//_action.EndInvoke(res);
SendLog?.Invoke($"ID[{_thread.ManagedThreadId}] 完成执行Action[{_action.Method.Name}] 耗时:{DateTime.Now.Subtract(begin).TotalMilliseconds}");
}
}
}
catch (Exception ex)
{
}
finally
{
}
Thread.Sleep(_sleeptime);
}
}
///
/// 插入任务
///
///
public BaseResult SetAction(Action action)
{
try
{
if (ActionStatus == ActionState.Ready)
{
_action = action;
ActionStatus= ActionState.Waiting;
return BaseResult.Successed;
}
return new BaseResult(false, "线程正忙,无法添加任务");
}
catch (Exception ex)
{
throw ex;
}
}
///
/// 停止线程工作
///
public void Stop()
{
try
{
isRunThread = false;
_action = null;
ActionStatus = ActionState.Init;
Thread.Sleep(1000);
_thread?.Join();
}
catch (Exception ex)
{
throw ex;
}
}
}
///
/// 线程工作状态
///
public enum ActionState
{
///
/// 初始化中
///
Init,
///
/// 待开始
///
Ready,
///
/// 等待开始
///
Waiting,
///
/// 任务执行中
///
Working
}
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: 有了Composition API后,有些场景或许你不需要pinia了
前言 日常开发时有些业务场景功能很复杂,如果将所有代码都写在一个vue组件中,那个vue文件的代码量可能就几千行了,维护极其困难。这时我们就需要将其拆分为多个组件,拆完组件后就需要在不同组件间共享数据和业务逻辑。有的小伙伴会选择将数据和业务逻辑都放到pinia…