单线程任务队列

<span style="font-weight: bold;">下边代码解决了 避免创建新线程 规避了线程池的创建过多线程 解决浪费资源问题  </span>
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace MyThreadPool
{
  /// <summary>
  /// 线程任务队列
  /// </summary>
  /// <typeparam name="T"></typeparam>
   public  class BackgroundTasks<T>
    {
       /// <summary>
       /// 带参数不带返回值的函数委托
       /// </summary>
       private Action<T> Function;

       /// <summary>
       /// 先进先出队列
       /// </summary>
       private Queue<T> list = new Queue<T>();

       /// <summary>
       /// 构造函数
       /// </summary>
       /// <param name="fun"></param>
       public  BackgroundTasks(Action<T> fun) {
           this.Function = fun;
           Thread th = new Thread(Run);
           th.IsBackground = true;
           th.Start();
       }
       /// <summary>
       /// 执行线程 方法队列
       /// </summary>
       private void Run()
       {
           while (true)
           {
               if (list.Count == 0)
               {
                   Thread.Sleep(10);
               }
               else
               {
                   T data;
                   lock (list)
                   {
                       data = list.Dequeue();
                   }
                   try
                   {
                       Function(data);
                   }
                   catch { }
                   Thread.Sleep(10);
               }

           }
       }
       /// <summary>
       /// 添加队列到线程中
       /// </summary>
       /// <param name="data"></param>
       public void Add(T data)
       {
           lock (list)
           {
               list.Enqueue(data);
           }
       }
    }
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace MyThreadPool
{
    class Program
    {
        static void Main(string[] args)
        {
            BackgroundTasks.Add((obj) => {
                Console.WriteLine("这个任务的添加时间是1:{0}", obj.ToString());
            },DateTime.Now.Millisecond);

            BackgroundTasks.Add((obj) =>
            {
                Console.WriteLine("这个任务的添加时间是2:{0}", obj.ToString());
            }, DateTime.Now.Millisecond);

            BackgroundTasks.Add((obj) =>
            {
                Console.WriteLine("这个任务的添加时间是3:{0}", obj.ToString());
            }, DateTime.Now.Millisecond);

            BackgroundTasks.Add((obj) =>
            {
                Console.WriteLine("这个任务的添加时间是4:{0}", obj.ToString());
            }, DateTime.Now.Millisecond);

            ///自定义线程队列 传入泛型参数,只创建一个线程
            BackgroundTasks<DateTime> task = new BackgroundTasks<DateTime>(obj =>
            {
                Console.WriteLine("这个任务的添加时间是5:{0}", obj.ToString());
            });
            task.Add(DateTime.Now);

            ///线程池的 方法 每次调用都创建新线程
            ThreadPool.SetMaxThreads(100, 1000);
            ThreadPool.QueueUserWorkItem((obj) => {
                Console.WriteLine("这个任务的添加时间是6:{0}", obj.ToString());
            }, DateTime.Now);
            Console.Read();
        }
    }

    /// <summary>
    /// 线程任务队列
    /// </summary>
    public class BackgroundTasks
    {
        /// <summary>
        /// 任务实体
        /// </summary>
        private class TaskEntity
        {
            public Action<object> Function;
            public object Data;
            public TaskEntity(Action<object> func, object data)
            {
                this.Function = func;
                this.Data = data;
            }
        }

        /// <summary>
        /// 先进先出队列
        /// </summary>
        static Queue<TaskEntity> list = new Queue<TaskEntity>();

        /// <summary>
        /// 构造函数 创建线程
        /// </summary>
        static BackgroundTasks() 
        {
            Thread thread = new Thread(Run);
            thread.IsBackground = true;
            thread.Start();
        }

        /// <summary>
        /// 执行线程 方法队列
        /// </summary>
        static void Run()
        {
            while (true)
            {
                if (list.Count == 0)
                {
                    Thread.Sleep(1000);
                }
                else
                {
                    TaskEntity entity;
                    lock (list)
                    {
                        entity = list.Dequeue();
                    }
                    try
                    {
                        entity.Function(entity.Data);
                    }
                    catch {}
                    Thread.Sleep(10); 
                }
            }
        }
        /// <summary>
        /// 添加任务队列
        /// </summary>
        /// <param name="func"></param>
        /// <param name="data"></param>
        public static void Add(Action<object> func, object data)
        {
            lock (list)
            {
                list.Enqueue(new TaskEntity(func, data));
            }
        }
      
    }
}
由于队列中的任务是单线程执行,可能会导致某些任务在很长时间后才会被执行到,或者重启IIS导致很多任务还没有被执行就被丢弃。无论怎么,这种设计还是适用于很多“一般情况”。
时间: 2024-10-03 16:48:40

单线程任务队列的相关文章

关于游戏服务器是多线程还是单线程的讨论

最近做有关于游戏服务器用单线程的好还是多线程的好的讨论 有同学问:服务端逻辑全单线程的模型,为了避免查询离线玩家数据造成阻塞,除了启动服务器全部加载以外还有更好的办法吗? 同学B: 单线程逻辑模型也属于很常用.逻辑本身不容易出问题. IO得全部分出去. 同学B: 用异步加载事件.数据加载完成后.再重新把任务排入单线程任务队列. 同学C: 各种活动NPC打完就要从场景消失  战斗线程和场景线程分不开 同学C: 场景线程依赖战斗的结果 同学C: 战斗的结果会影响NPC在场景的动态显示 同学C: 然后

Android 中 SQLite 性能优化

数据库是应用开发中常用的技术,在Android应用中也不例外.Android默认使用了SQLite数据库,在应用程序开发中,我们使用最多的无外乎增删改查.纵使操作简单,也有可能出现查找数据缓慢,插入数据耗时等情况,如果出现了这种问题,我们就需要考虑对数据库操作进行优化了.本文将介绍一些实用的数据库优化操作,希望可以帮助大家更好地在开发过程中使用数据库. 建立索引 很多时候,我们都听说,想要查找快速就建立索引.这句话没错,数据表的索引类似于字典中的拼音索引或者部首索引. 索引的解释 重温一下我们小

js 运行机制

javascript的运行机制 单线程 任务队列 事件和回调函数 异步IO javascript最大的特点就是单线程,也就是在同一时间只能做一件事情.那为什么会是单线程呢?这还要从javascript的用途来看.javascript的主要用途就是与用户互动以及DOM操作(浏览器中),这就决定的了它必须是单线程的,不然会出现很严重的问题.比如当有两个线程同时对一个DOM进行操作的时候,浏览器不知道到底以哪个线程为准.既然是单线程的,又怎样保证性能呢?接下来我们就来看看javascript的运行机制

c# 异步任务队列(可选是否使用单线程执行任务,以及自动取消任务)

使用demo,(.net framework 4.0 自行添加async wait 扩展库) class Program { static void Main(string[] args) { Console.WriteLine("主线程"+Thread.CurrentThread.ManagedThreadId); var asyncTaskQueue = new AsyncTaskQueue { AutoCancelPreviousTask = true, // 自动取消之前的任务

js单线程、js任务队列、异步操作

2017.9.22[面试阶段] 一:js由来 JavaScript 1995年首次设计在浏览器上,领导者为了让他看起来更像java,所以起名JavaScript: js是兼容ECMA标准,也称为ECMAScript:js是一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言: 他的解释器称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早用在HTML上,添加动态功能 二:单线程是js的一大特性 不像其他语言如java一样多线程,不用考虑线程同步的问题: js是用户

JavaScript的单线程与任务队列

一.JavaScript为什么设计为单线程? JavaScript语言的一大特点就是单线程,换言之就是同一个时间只能做一件事. for(var j = 0; j < 5; j++) { console.log(j); } console.log('end'); 上面的代码,只有for循环执行完毕,才会执行end: JavaScript的单线程,与它的用途有关.作为浏览器脚本语言,JavaScript的主要用途就是与用户互动,以及操作DOM.这决定了它只能是单线程,否则会带来很复杂的同步问题. 假

Javascript引擎单线程机制及setTimeout执行原理说明

setTimeout用法在实际项目中还是会时常遇到.比如浏览器会聪明的等到一个函数堆栈结束后才改变DOM,如果再这个函数堆栈中把页面背景先从白色设为红色,再设回白色,那么浏览器会认为DOM没有发生任何改变而忽略这两句话,因此我们可以通过setTimeout把“设回白色”函数加入下一个堆栈,那么就可以确保背景颜色发生过改变了(虽然速度很快可能无法被察觉). 总之,setTimeout增加了Javascript函数调用的灵活性,为函数执行顺序的调度提供极大便利. 然后,我们从基础的层面来看看:理解J

单线程的JS引擎

先来思考一个问题,JS 是单线程的么?为什么单线程的JavaScript却能让AJAX异步发送和回调请求,还有setTimeout也看起来像是多线程的?还有non-blocking IO, event loop等概念. 目录: JS单线程 浏览器多线程 setTimeout(func, 0) 的应用场景 setTimeout与setInterval 参考资料 TODO: 接下来,梳理JS的并发模型与 Event Loop https://developer.mozilla.org/zh-CN/d

单线程 异步 同步 阻塞 非阻塞

Javascript是单线程的深入分析 首先一个引子:为什么JavaScript是单线程的却能让AJAX异步发送和回调请求,还有setTimeout也看起来像是多线程的? 先看例子1: 1 function foo() { 2 console.log( 'first' ); 3 setTimeout( ( function(){ console.log( 'second' ); } ), 5); 4 } 5 for (var i = 0; i < 1000000; i++) { 6 foo();