c# 后台任务自动执行

如果有些任务需要在后台自动执行,且时不时需要添加一个任务,且按照优先级顺序执行,那么可以参考本文的方法。

后台任务类

定义一个后台任务类BackgroundTaskThread,其中Start方法是用来启动任务的,循环查询是否有添加任务,外部一般就调用AppendTask来添加任务。循环任务发现任务有添加后,会自动执行。如果有多个任务,会按加入的顺序一个一个执行。

csharp 复制代码
public class BackgroundTaskThread
{
    /// <summary>
    /// 任务列表
    /// </summary>
    private List<TaskItem> TaskItems = new List<TaskItem>();
    /// <summary>
    /// 等待时间
    /// </summary>
    public int MillSeconds = 1000;
    /// <summary>
    /// 自动重置
    /// </summary>
    public AutoResetEvent TaskSet = new AutoResetEvent(false);
    /// <summary>
    /// 任务取消标识
    /// </summary>
    public CancellationTokenSource Source { get; set; } = new CancellationTokenSource();
    /// <summary>
    /// 日志
    /// </summary>
    public ILog Log { get; set; }
    /// <summary>
    /// 线程数量
    /// </summary>
    public int ThreadNum { get; private set; }
    /// <summary>
    /// 任务线程
    /// </summary>
    public List<Task> TaskThreads = new List<Task>();
    /// <summary>
    /// 启动
    /// </summary>
    /// <param name="taskTimeSpan">任务扫描间隔</param>
    /// <param name="taskNum">任务数量</param>
    public void Start(int taskTimeSpan, int taskNum)
    {
        ThreadNum = taskNum;

        for (int i = 0; i < taskNum; i++)
        {
            MillSeconds = taskTimeSpan;
            Task task = new Task(BackgroundThread);
            task.Start();
            TaskThreads.Add(task);
        }
        
    }
    /// <summary>
    /// 后台任务
    /// </summary>
    private void BackgroundThread()
    {
        try
        {
            while (!Source.Token.IsCancellationRequested)
            {
                var item = GetOrSetTaskItem(true, null);
                if(item == null)
                {
                    TaskSet.WaitOne(MillSeconds);
                }
                else
                {
                    try
                    {
                        item.Task.Invoke(item.Param);
                    }
                    catch (Exception ex)
                    {
                        Log.error("任务 : ", item.Name, " 异常停止.,..", ex);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Log.error("后台任务线程异常退出....", ex);
        }
    }

    /// <summary>
    /// 读取或者
    /// </summary>
    /// <param name="isGet">是否是获取</param>
    /// <param name="item">任务项</param>
    /// <returns></returns>
    protected TaskItem GetOrSetTaskItem(bool isGet, TaskItem item)
    {
        lock (this)
        {
            if (isGet)
            {
                if (TaskItems.Count == 0)
                    return null;
                item = TaskItems[0];
                TaskItems.RemoveAt(0);
                return item;
            }
            else
            {
                TaskItems.Add(item);
                return item;
            }
        }
    }

    /// <summary>
    /// 追加任务
    /// </summary>
    /// <param name="task"></param>
    /// <param name="param"></param>
    public void AppendTask(Action<object> task, object param)
    {
        GetOrSetTaskItem(false, new TaskItem() { Task = task, Param = param });
        TaskSet.Set();
    }
    /// <summary>
    /// 释放
    /// </summary>
    public void Dispose()
    {
        if(TaskThreads.Count > 0)
            Source.Cancel();

        TaskItems.Clear();
    }
}

实际任务

csharp 复制代码
public class DoSomethingTaskThread : BackgroundTaskThread
{
    public void AppendSomething(object data)
    {
        AppendTask(DoSomething, data);
    }
    private void DoSomething(object data)
    {
        //TODO
    }
}

外部调用

当然,最好把DoSomethingTaskThread这个子类做成单例,后面直接

csharp 复制代码
//启动任务,同步的话线程数传1,异步的话线程数可以传多点
DoSomethingTaskThread.Start(1000,1);

//添加任务
DoSomethingTaskThread.AppendSomething(new object());
相关推荐
“抚琴”的人42 分钟前
C#—LINQ详解及汇总
开发语言·c#·linq
pchmi2 小时前
C# OpenCV机器视觉:图像分割(让照片中的物体各自“安家”!)
opencv·c#·opencvsharp
“抚琴”的人3 小时前
C#—扩展方法
java·开发语言·c#
CV大法好4 小时前
C#中的匿名方法、Lambda表达式、泛型委托
开发语言·c#
小码编匠5 小时前
C# 使用心跳机制实现TCP客户端自动重连
后端·c#·.net
monstercl5 小时前
【C#】预处理指令
服务器·数据库·c#
pchmi6 小时前
C# OpenCV机器视觉:图像拼接
开发语言·opencv·c#
time6 小时前
适用于.net的操作excel的库
c#·.net·excel·avalonia
Olivia_vivi10 小时前
c#委托delegate学习
c#