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());
相关推荐
z落落5 小时前
C# 继承:父子构造函数 + base 关键字 +五大访问修饰符(同项目+跨项目 全覆盖)
开发语言·c#
海盗12345 小时前
C#中PDF操作-QuestPDF页面设置与布局
java·pdf·c#
玩c#的小杜同学6 小时前
一周 AI 新鲜事|2026.05.25—2026.05.31
人工智能·程序人生·ai·c#·程序员创富
周杰伦fans6 小时前
C# 异常继承深度解析:从设计原则到 sealed 关键字的奥秘
java·jvm·c#
多巴胺耐受7 小时前
【WPF】炫酷的科技报警弹窗
科技·c#·wpf
刘欣的博客7 小时前
LiteNetLib WinForm Demo
数据库·microsoft·c#
魔法阵维护师9 小时前
从零开发游戏需要学习的c#模块,第三十五章(打包发布 —— 让别人玩你的游戏)
学习·游戏·c#
iCxhust9 小时前
C# 程序,实现二进制文件十六进制查看器,支持按行定位
开发语言·单片机·嵌入式硬件·c#·微机原理·8086最小系统·8088单板机
Xin_ye1008610 小时前
C# 零基础到精通教程 - WPF 专题二:数据绑定与 MVVM
开发语言·c#·wpf
Xin_ye1008610 小时前
C# 零基础到精通教程 - WPF 专题一:WPF 入门与 XAML 基础
c#·wpf