Reference: http://blog.csdn.net/sq_zhuyi/article/details/6869661
In web development, in order to reduce page wait times to improve the user experience, we tend to put some time-wasting operations into the new thread in the background to run.
The simple implementation code is:
// Code One New Thread (() ={ //dosomething}). Start ();
View Code
However, it is unrealistic to do this for a high-volume URL, where each operation opens a new thread and eventually hangs up because the CPU is overwhelmed.
A better practice is to use thread queues.
For thread queue ThreadPool.QueueUserWorkItem A lot of people should be not unfamiliar, look at Microsoft's explanation below:
Queues a method for execution and specifies the object that contains the data used by the method. This method executes when the thread pool threads become available.
It does this by putting some operations into another thread outside the current thread, which is simple to use:
// Code two ThreadPool.QueueUserWorkItem (stat = { //dosomethingnull);
View Code
The advantage of it relative to code one is that it takes advantage of idle threads that have already been created, and queues without idle, without blindly creating them all the time.
But it does not get rid of the problem of creating new threads: Too many threads consume more resources. It is not difficult for us to think of why we do not own a queue, let them in the same thread to execute one after the other? For this, I have written a simple implementation class:
1 Public classBackgroundtasks2 {3 Private classtaskentity4 {5 PublicTaskentity (action<Object> Func,Objectdata)6 {7 This. Function =func;8 This. Data =data;9 }Ten Publicaction<Object>Function; One Public ObjectData; A } - Staticqueue<taskentity> list =NewQueue<taskentity>(); - the Staticbackgroundtasks () - { -Thread th =NewThread (RunTask); -Th. IsBackground =true; + th. Start (); - } + Static voidRunTask () A { at while(true) - { - if(list. Count = =0) - { -Thread.Sleep ( +); - } in Else - { to taskentity entity; + Lock(list) - { theentity =list. Dequeue (); * } $ TryPanax Notoginseng { - entity. Function (entity. Data); the } + Catch { } AThread.Sleep (Ten); the } + } - } $ $ Public Static voidADD (action<Object> Func,Objectdata) - { - Lock(list) the { -List. Enqueue (Newtaskentity (func, data));Wuyi } the } - Wu}View Code
The use of this class is simple:
Backgroundtasks.add ((obj) ={Console.WriteLine (" This task was added at: {0}" as DateTime);}, DateTime.Now);
There is also an "instance version", which is to create a task queue for each method individually:
1 Public classBackgroundtasks01<t>2 {3 PrivateAction<t>Function;4 5 Privatequeue<t> list =NewQueue<t>();6 7 PublicBackgroundTasks01 (action<t>func)8 {9 This. Function =func;Ten OneThread th =NewThread (RunTask); ATh. IsBackground =true; - th. Start (); - } the Private voidRunTask () - { - while(true) - { + if(list. Count = =0) - { +Thread.Sleep ( +); A } at Else - { - T data; - Lock(list) - { -data =list. Dequeue (); in } - Try to { + Function (data); - } the Catch { } *Thread.Sleep (Ten); $ }Panax Notoginseng } - } the + Public voidAdd (T data) A { the Lock(list) + { - list. Enqueue (data); $ } $ } - -}View Code
Blog class:
classblog{Private int_blogid =0; Public intBlogId {Get{return_blogid;} Set{_blogid =value;} } Private string_blogname =""; Public stringBlogname {Get{return_blogname;} Set{_blogname =value;} }}View Code
Invocation Example:
//Method Two:varBG =NewBackgroundtasks01<blog> (Blog) ={Console.WriteLine ("Blogname:{0},blogid:{1}", blog. Blogname, blog. BLOGID);});inti =0; while(I++ < -) {bg. ADD (NewBlog () {BlogId = i, Blogname ="Default" });} Console.ReadLine (); BG. ADD (NewBlog () {BlogId = +, Blogname ="Zhang San"}); bg. ADD (NewBlog () {BlogId =1001, Blogname ="John Doe"});View Code
This design solves both asynchronous execution and resource-occupying problems.
But there is no perfect thing in the world, the code is the same, because the task in the queue is single-threaded execution, which can cause some tasks to be executed after a long time, or restarting IIS causes many tasks to be discarded without being executed.
However, this design is suitable for many "general situations".
Performance issues with ThreadPool.QueueUserWorkItem