Ответ
C# предоставляет многоуровневую модель многопоточности, от низкоуровневых потоков ОС до высокоуровневых абстракций.
1. Классические потоки (System.Threading.Thread)
Прямое создание и управление потоками операционной системы. Ресурсоёмко, так как каждый поток имеет свой стек (обычно 1 МБ).
var thread = new Thread(() =>
{
Thread.Sleep(1000);
Console.WriteLine("Работа из потока: " + Thread.CurrentThread.ManagedThreadId);
});
thread.IsBackground = true; // Фоновый поток не помешает завершению приложения
thread.Start();
2. Пул потоков (System.Threading.ThreadPool)
Ключевой компонент для эффективного управления потоками. CLR создаёт и переиспользует набор рабочих потоков, избегая накладных расходов на их создание/уничтожение.
ThreadPool.QueueUserWorkItem(state =>
{
// Эта работа будет выполнена одним из потоков пула
Console.WriteLine("Пул потоков, ID: " + Thread.CurrentThread.ManagedThreadId);
});
3. Задачи (System.Threading.Tasks.Task)
Рекомендуемая высокоуровневая абстракция. Task представляет собой асинхронную операцию, которая обычно выполняется в потоке из пула.
// Запуск фоновой задачи
Task.Run(() => Console.WriteLine("Выполнено задачей"));
// Задачи с продолжением (continuation)
Task.Run(() => 42)
.ContinueWith(prevTask => Console.WriteLine("Результат: " + prevTask.Result));
4. Асинхронное программирование (async/await)
Модель, позволяющая писать неблокирующий код, который выглядит как синхронный. Ключевое отличие — await не блокирует текущий поток, а возвращает управление вызывающему коду.
public async Task<string> DownloadDataAsync(string url)
{
using var httpClient = new HttpClient();
// При await поток не блокируется. Когда ответ готов,
// выполнение продолжается (возможно, в другом потоке из пула).
string data = await httpClient.GetStringAsync(url);
return data.ToUpper();
}
5. Средства синхронизации Для безопасного доступа к общим данным используются:
lock(Monitor) — для взаимного исключения в рамках одного процесса.Mutex— для синхронизации между процессами.Semaphore/SemaphoreSlim— для ограничения числа одновременных доступов к ресурсу.ConcurrentCollections(ConcurrentDictionary,ConcurrentQueue) — потокобезопасные коллекции.CancellationToken— для кооперативной отмены операций.
Практическое правило: Используйте Task и async/await для операций ввода-вывода (I/O-bound) и Task.Run для распараллеливания CPU-bound операций, чтобы эффективно использовать пул потоков.