Tasks and threads
لم يُترجم بعد؛ يُعرض باللغة الإنجليزية
A thread is a path through your code that the operating system runs on a CPU core. Threads are costly, so .NET keeps a thread pool: a few worker threads that take jobs from a queue. Follow a program that splits 1 to 100 into two halves: Task.Run queues each half and returns a Task<int> at once, two workers add them up in parallel on two cores, and await Task.WhenAll collects 1275 and 3775 so the program prints 5050.
5 أسئلة سريعة
اختر إجابة لتعرف السبب. تُحفَظ نتيجتك مع تقدّمك.
01What does Task.Run(() => Sum(1, 50)) do?
Task.Run queues the work on the thread pool and immediately returns a Task<int> that stands for it. A pool worker runs the job later; the caller does not wait.
02Why does .NET keep a thread pool instead of making a new thread for every job?
Each thread needs its own stack and operating system setup. Pool workers are reused job after job, so thousands of tasks can share a few threads.
03t1 adds 1 to 50 and t2 adds 51 to 100. What is r after int[] r = await Task.WhenAll(t1, t2);?
Task.WhenAll returns the results in the same order as the tasks you passed, whatever order they finished in: r[0] is t1's 1275, r[1] is t2's 3775.
04On a CPU with two cores, why can the two sums run at the same moment?
A core runs one thread at a time. With two cores, two worker threads (each running one job) can truly run at the same time: in parallel.
05Which sentence best tells a task apart from a thread?
A Task describes work and, when done, its result (or its exception). Threads are the workers. The pool runs many tasks on a few threads.
المسرد
- Thread
- One path through your code that the operating system runs on a CPU core, one instruction after another. Every program starts with one: the main thread.
- Core
- One independent processor inside a CPU. Each core runs one thread at a time, so more cores means more threads at the same instant.
- Thread pool
- .NET's set of ready worker threads plus a queue of jobs. Workers are reused, so jobs avoid the cost of new threads.
- Task / Task<T>
- An object that stands for a piece of work in progress and, when it finishes, its result of type T (read with await or .Result).
- Task.Run
- Queues a job (usually a lambda) on the thread pool and returns a Task for it straight away.
- Task.WhenAll
- Makes one task that completes when all the given tasks have; for Task<T> its result is an array of their results, in order.
- Parallel
- Really running at the same moment, on different cores.
- Blocking
- Making a thread stop and wait, doing nothing, for example by reading .Result before a task is done. await waits without blocking.
الملاحظات والمصادر
- Program.cs is real C#. Below the four lines it defines the local function static int Sum(int lo, int hi) { int s = 0; for (int i = lo; i <= hi; i++) s += i; return s; }. dotnet run prints 5050.
- The picture is tidy on purpose. A real pool has as many workers as it decides (by default it adds them quickly up to the number of processors, then more slowly), and which worker runs which job, and in what order, can change from run to run. Only the results and their order in r are fixed.
- With await in top-level statements the compiler makes an async method plus a hidden real Main that waits for it with GetAwaiter().GetResult(). That is why the main thread just waits while the pool does the work.
- A console app has no SynchronizationContext, so after await the method continues on a thread pool thread; which one can vary. In a desktop app with a UI thread, await returns to the UI thread instead.
- Task.Run suits CPU-bound work like these sums. For waiting on input and output, such as a web request or a file, use the async methods (for example HttpClient.GetStringAsync) with await: no thread sits waiting at all.
- Reading t1.Result before t1 is done blocks the calling thread until it finishes. await does not block a thread, which is why it is preferred.
- Microsoft Learn: Threads and threading
- Microsoft Learn: The managed thread pool
- Microsoft Learn: Task-based asynchronous programming
- Microsoft Learn: Task.Run method
- Microsoft Learn: Task.WhenAll method
- Microsoft Learn: TaskStatus enum
- Microsoft Learn: Task<TResult>.Result property
- Microsoft Learn: Async Main (C# 7.1 feature specification)
- Microsoft Learn: Async/Await best practices (console apps and the thread pool context)
- Microsoft Learn: Processes and threads (Windows)
اختبار يتاح بعد الخطوة الأخيرة.