后台任务的形式
在日常开发中总是免不了接触到后台任务,如:定时清理、Socket通讯等。一般来说后台任务根据线程模型可以分为:单线程、多线程、线程池。
单线程
如果后台任务需要严格按时序进行,而且任务和任务之间不能并行处理的话,应该选用单线程实现。
多线程
如果后台任务之间可以并行处理就可以选用多线程模式实现,因为线程的开启和销毁都是需要资源的,所以有如下公式:
执行总消耗 = 开启线程消耗 + 任务消耗 + 销毁线程消耗
因此,任务的执行频率要尽可能的低,任务的执行耗时要尽可能的大,否则系统的资源将大部分都消耗在线程的开启和销毁中。
线程池
线程池是一种多线程处理形式,处理过程中将任务添加到队列然后通知提前创建好的工作线程,然后工作线程再从任务队列中获取任务并执行。根据上面的公式,线程池是提前创建好一定数量的工作线程,所以线程的开启和销毁消耗已经是固定了,适合任务量大的任务类型。
代码实现
代码先上为敬。
1.JobResult.cs
/// <summary>
/// 工作执行结果
/// </summary>
public class JobResult
{
/// <summary>
/// 是否成功
/// </summary>
public bool Success {
get; set; }
/// <summary>
/// 返回信息
/// </summary>
public string Message {
get; set; }
/// <summary>
/// 可能会有的附加数据
/// </summary>
public object Data {
get; set; }
public JobResult()
{
Success = true;
}
public void OperateFail(string msg)
{
Success = false;
Message = msg;
}
}
2.BaseJob.cs
/// <summary>
/// 工作项基类
/// </summary>
public abstract class BaseJob
{
/// <summary>
/// 开始前回调
/// </summary>
public Action<BaseJob> Begin;
/// <summary>
/// 结束后回调
/// </summary>
public Action<BaseJob, JobResult> Finished;
public void Run()
{
JobResult result = default;
Begin?.Invoke(this);
try
{
result = Execute();
}
catch(Exception ex)
{
result.OperateFail(ex.Message);
result.Data = ex;
}</