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());
相关推荐
软件黑马王子5 小时前
C#初级教程(4)——流程控制:从基础到实践
开发语言·c#
水煮庄周鱼鱼10 小时前
C# 入门简介
开发语言·c#
软件黑马王子10 小时前
Unity游戏制作中的C#基础(6)方法和类的知识点深度剖析
开发语言·游戏·unity·c#
Nicole Potter11 小时前
请说明C#中的List是如何扩容的?
开发语言·面试·c#
gu2013 小时前
c#编程:学习Linq,重几个简单示例开始
开发语言·学习·c#·linq
pchmi17 小时前
CNN常用卷积核
深度学习·神经网络·机器学习·cnn·c#
yuanpan17 小时前
23种设计模式之《组合模式(Composite)》在c#中的应用及理解
开发语言·设计模式·c#·组合模式
滴_咕噜咕噜18 小时前
C#基础总结:常用的数据结构
开发语言·数据结构·c#
万兴丶1 天前
Unity 适用于单机游戏的红点系统(前缀树 | 数据结构 | 设计模式 | 算法 | 含源码)
数据结构·unity·设计模式·c#
程序猿多布1 天前
C#设计模式 学习笔记
设计模式·c#