Threadpool. queueuserworkitem performance problems

Source: Internet
Author: User

In web development, in order to reduce the page wait time and improve the user experience, we usually put some time-wasting operations in the new thread to run in the background.

The simple implementation code is:

// Code 1 new thread () =>{// do something}). Start ();

However, it is unrealistic to do this for a website with a large number of requests-each operation must start a new thread, and the website will eventually be suspended due to the CPU overload.

A better way is to use a thread queue.

Many people should be familiar with thread queue threadpool. queueuserworkitem. Let's look at Microsoft's explanation below:

Queues methods for execution and specifies the objects that contain the data used by the method. This method is executed when a thread pool thread becomes available.


Its function is to put some operations into another thread other than the current thread for execution. Its usage is simple:

// Code 2 threadpool. queueuserworkitem (STAT =>{// do something}, null );

Compared with code 1, it uses Idle threads that have been created. If there is no idle thread, it queues without blindly creating it.

But it does not get rid of the problem of "Creating a New thread": too many threads will occupy more resources. From this we can hardly imagine why we don't have to create a queue ourselves so that they can be executed one by one in the same thread? In this regard, I wrote a simple implementation class:

    public class BackgroundTasks    {        private class TaskEntity        {            public TaskEntity(Action<object> func, object data)            {                this.Function = func;                this.Data = data;            }            public Action<object> Function;            public object Data;        }        static Queue<TaskEntity> list = new Queue<TaskEntity>();                static BackgroundTasks()        {            Thread th = new Thread(RunTask);            th.IsBackground = true;            th.Start();        }        static void RunTask()        {            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);                }            }        }        public static void Add(Action<object> func, object data)        {            lock (list)            {                list.Enqueue(new TaskEntity(func, data));            }        }    }

This class is easy to use:

Backgroundtasks. Add (OBJ) => {

Console. writeline ("the task was added at {0}", OBJ as datetime );

}, Datetime. Now );

Another "instance version" is to create a task queue for each method:

    public class BackgroundTasks<T>    {        private Action<T> Function;        private Queue<T> list = new Queue<T>();        public BackgroundTasks(Action<T> func)        {            this.Function = func;            Thread th = new Thread(RunTask);            th.IsBackground = true;            th.Start();        }        private void RunTask()        {            while (true)            {                if (list.Count == 0)                {                    Thread.Sleep(1000);                }                else                {                    T data;                    lock (list)                    {                        data = list.Dequeue();                    }                    try                    {                        Function(data);                    }                    catch { }                    Thread.Sleep(10);                }            }        }        public void Add(T data)        {            lock (list)            {                list.Enqueue(data);            }        }    }

Call example:

var bg = new BackgroundTasks<Blog>((blog) => {     Console.WriteLine(blog.BlogId); });int i = 0;while (i++ < 1000){    bg.Add(new Blog() { BlogId = i });}

This design solves both asynchronous execution and resource occupation.

But there is no perfect thing in the world, and the same is true for the Code. Because the tasks in the queue are executed in a single thread, some tasks may be executed after a long time, or restart IIS to discard many tasks that have not been executed.

In any case, this design still applies to many "general situations ".

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.