Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
vermeir_nico_introducing_net_6_getting_started_with_blazor_m.pdf
Скачиваний:
19
Добавлен:
26.06.2023
Размер:
11.64 Mб
Скачать

Chapter 11 Advanced .NET 6

A Look at the Threadpool

The threadpool in .NET is a pool of background threads that we can schedule work on. Depending on the system your application is running on, the runtime will create a set of background workers. Should we request more threadpool threads than the amount available, it will create extra background threads and keep those alive for future use. Since the threadpool threads are background threads, they cannot keep the

process alive. Once all foreground threads have exited, the application will close and all background threads will terminate.

The threadpool has been favored over creating threads manually ever since .NET 4. The main reason is performance; threadpool threads already exist; they just need to be given a unit of work, while manual threads still need to be created and that creation is an expensive operation. An easy example of using the threadpool can be created by using the Task Parallel Library, or TPL.

Listing 11-3.  Using the Task Parallel Library

var strings = new List<string>();

for (int i = 0; i < 1000; i++)

{

strings.Add($"Item {i}");

}

Parallel.ForEach(strings, _ =>

{

Console.WriteLine(_); Thread.Sleep(1000);

});

We have a list of 1000 strings. Using the TPL, we can loop over this in a parallel way with Parallel.ForEach. For each item in the list, work will be scheduled on a threadpool thread. The Thread pane in Visual Studio can visualize this.

301

Chapter 11 Advanced .NET 6

Figure 11-3.  Visualizing threadpool threads

Running a foreach loop in parallel also means that the order of the outcome can be unpredictable.

Figure 11-4.  Parallel ForEach output

A different way to loop over a collection in a parallel manner is using the AsParallel extension method. AsParallel is a method in the LINQ library. It returns a ParallelQuery object. By itself it does not do any parallelization; we need to execute a LINQ query on the ParallelQuery object it returns. Listing 11-4 shows how to use this method.

302

Chapter 11 Advanced .NET 6

Listing 11-4.  Using the AsParallel method

var strings = new List<string>();

for (int i = 0; i < 1000; i++)

{

strings.Add($"Item {i}");

}

foreach (string item in strings.AsParallel().Select(_ => _))

{

Console.WriteLine(item);

Thread.Sleep(1000);

}

There is no major difference in using Parallel.ForEach versus AsParallel. The way to use it differs, but the results are similar.

The static ThreadPool class in .NET can tell us how many threadpool workers we can have simultaneously. Listing 11-5 shows how; Figure 11-5 shows the result on my Intel i7 device with 32GB of RAM.

Listing 11-5.  Listing ThreadPool information

ThreadPool.GetMaxThreads(out int workerthreads, out int completionports);

Console.WriteLine($"Max number of threads in the threadpool: {workerthreads}");

Console.WriteLine($"Max number of completion ports in the threadpool: {completionports }");

Figure 11-5.  Max number of workers in the threadpool

The threadpool consists of two types of threads: worker threads and completion ports. Completion ports are used for handling asynchronous I/O requests. Using completion ports for I/O requests can be much more performant than creating your own

303