C # multithreaded Tour (3)--thread pool

Source: Internet
Author: User
Tags call back

Original address: C # multithreaded Tour (3)--thread pool

C # multithreaded Tour directory:

C # multithreaded Tour (1)--Introduction and basic concepts

C # multithreaded Tour (2)--Create and start threads

C # multithreaded Tour (3)--thread pool

C # multithreaded Tour (4)--Synchronization Essence


Back to the top of the code download

Thread_ Blog Park _cnblogs_jackson0714.zip

code example for the first ~ third article:

Back to top one, introduction

No matter when you start a thread, hundreds of milliseconds will be spent tidying up a new local variable stack. Each thread consumes 1MB of memory by default . The thread pool cuts these overhead by sharing and recycling threads, allowing multithreading to be applied at a very granular level without loss of performance. This is useful when taking full advantage of multi-core systems to execute parallel code that is computationally intensive.

The thread pool also maintains a limit on the total number of threads, which allows the threading to run more smoothly. Too many threads will cause administrative burdens and cause the CPU cache to be small, causing the operating system to not run. Once a limit arrives, thejob waits until another completion begins. This makes it possible for any parallel application, such as a Web server(the synchronization method is an advanced technique that can be used more efficiently by threads in the thread pool).

Here are a few ways to get into the thread pool:

    1. Through the Task Parallel Library(. NET 4.0)
    2. By calling ThreadPool.QueueUserWorkItem
    3. By Asynchronous Delegates
    4. by Backgroundworkder

The following structure uses the thread pool directly:

    1. Wcf,remoting,asp.net,asmx WEB Services Application servers
    2. System.Timers.Timer and System.Threading.Timer
    3. The Framework methods is terminated by Async, such as WebClient (the event-based Asynchronous Pattern) and most of the BeginXXX Method (the asynchronous Programming model pattern)
    4. Plinq

Task Parallel Library (TPL) and PLINQ are fully effective and high-grade, and even when the thread pool is unimportant, you will also want to use them to assist with multithreading.

Now let's take a quick look at how we use the Task class to implement a simple delegate that runs on a thread pool.

Here's what to look for when using the thread pool:

    1. You cannot set the name of a thread because setting the name of the thread will make debugging more difficult ( even if you can attach a description when you are debugging in the VS thread window).
    2. Threads in the thread pool are always background threads (this is usually not a problem).
    3. Blocking a thread may trigger a delay during the start of the application, unless you call threadpool.setminthreads

You cannot arbitrarily change the priority of a thread in a pool - because the priority is reverted to normal when it releases the pool.

You can query whether the thread is a thread in a pool that is running through property Thread.CurrentThread.IsThreadPoolThread Properties

Back to Topii. entering the thread pool through TPL

You can use the Task class in the Taskparallel Library to easily enter the thread pool. This Task class is described in the Framework 4.0 : If you are familiar with the old structure, consider replacing the non-generic task class with ThreadPool.QueueUserWorkItem, replace the asunchoronous delgates with the generic task< Tresult>. The latest structure is faster, more convenient, and more complex.

To use a non-generic task class, call the Task.Factory.StartNew method and pass the method into the delegate.

Task.Factory.StartNew returns a task object that you can use to monitor the task, forexample, you can call its wait method until it finishes.

12345678910111213 staticvoidMain(string[] args){    Task task =  Task.Factory.StartNew(Go);    task.Wait();    Console.ReadKey();}staticvoidGo(){    Console.WriteLine("From the thread pool start...");    Thread.Sleep(3000);    Console.WriteLine("From the thread pool end");}

When you invoke the Wait method for a task, an unhandled exception is easily re-thrown onto the host thread. (If you do not call the Wait method but discard the task, an unhandled exception will shut down the process)

The generic task<tresult> class is a subclass of a non-generic Task. It lets you get a return value from this task that has already been executed. In the following example, we use task<tresult> to download a Web page

12345678910111213141516171819 staticvoidMain(string[] args){    Task<string> task = Task.Factory.StartNew<string>(        () => DownloadString("http://www.baidu.com"));    //调用其他方法    //    //可以用task的Result的属性来获得task返回值。    //如果这个任务还在运行,当前的主线程将会被阻塞,直到这个任务完成。    stringresult = task.Result;}staticstringDownloadString(stringuri){    using(varwc = newSystem.Net.WebClient())    {        returnwc.DownloadString(uri);    }}

The Task Parallel Library has many functions, especially to improve the performance of multi-core processors. We will continue to discuss TPL in parallel programming.

Back to Topthird, no TPL into the thread pool

If your application is an earlier version of the. NET Framework ( prior to 4.0), you will not be able to use the TPL. You must use the old structure to enter the thread pool:

ThreadPool.QueueUserWorkItem and asynchoronous delegates. The difference between the two is that asynchronous delegates lets you return data from the thread. Asynchronous delegates collects any exception returned to the caller.

To use QueueUserWorkItem, simply call this method to run the delegate on the thread pool.

1234567891011 staticvoidMain(string[] args){    ThreadPool.QueueUserWorkItem(Go);    ThreadPool.QueueUserWorkItem(Go, 123);    Console.ReadKey();}staticvoidGo(objectdata){    Console.WriteLine("A from thread pool! "+ data);}

Our target method goobjectwaitcallback delegates). This will provide a simple way to pass the data into the method, just like parameterizedthreadstarttask,queueuserworkitem Does not return an object to help you manage execution later. Also, you have to explicitly write the code in the target method to handle the exception in -

ThreadPool.QueueUserWorkItem does not provide a mechanism to get its return value from an already completed thread. Asynchronous Delegate invocations (asynchronous delegates for short) solves this problem by allowing any number of typed parameters to be passed in two directions. In addition, unhandled exceptions on asynchronous delegates are easily re-thrown on the original thread (more precisely, this thread is called EndInvoke), so there is no need to display processing.

Do not confuse asynchronous delegates and asynchronous method (methods begin with begin and end, such as File.beginread/file.endread). Asynchronous methods are superficially based on simple protocols, but they exist to solve a more difficult problem.

Here's how to start a worker task with a asynchronous delegate:

    1. instantiates a delegate for the method that you want to run in parallel func delegates
    2. Delegatebegininvoke Iasyncresult return value. begininvoke
    3. When you need this result, call ZH-CN endinvokedelegateiasyncresult object.

In the following example, we use a asynchronous delegate invocation to run a simple method that runs concurrently with the main thread, and this method returns the length of a string:

1234567891011121314151617 staticvoidMain(string[] args){    Func<stringint> t = Go;    IAsyncResult result = t.BeginInvoke("test"nullnull);    //    // ... 这里可以执行其他并行的任务    //    intlength = t.EndInvoke(result);    Console.WriteLine("String lenth is: "+ length);    Console.ReadKey();}staticintGo(stringmesssage){    returnmesssage.Length;}

EndInvoke do three things. First, if asynchronous delegate does not complete execution, it waits for it to complete. Second, receive the return value (as well as any ref or out parameters). Third, return any unhandled thread exceptions to the thread that called it.

Note: If you use asynchronous delegate to invoke a method that does not return a value, you need to call EndInvoke technically. In practice, this is an open debate; no EndInvoke alarm to manage punishment not compiled by! If you choose not to call EndInvoke, however, you need to consider the exception of the thread to avoid a silent failure.

When you invoke the BeginInvoke method, you can specify a call back delegate- a method that can receive a IAsyncResult object. It will be called automatically after the delegate method is completed, which allows the thread that is being started to forget asynchronous Delegate, but it needs a little extra work at the end of call back.

C # multithreaded Tour (3)--thread pool

Related Article

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.