Іменування потоків
Потік можна поименовать, використовуючи властивість Name. Це надає велику зручність при налагодженні: імена потоків можна вивести в Console.WriteLine і побачити у вікні Debug – Threads у Microsoft Visual Studio. Ім'я потокові може бути призначене в будь-який момент, але тільки один раз – при спробі змінити його буде сгенерировано виключення.
Головному потокові додатка також можна призначити ім'я – у наступному прикладі доступ до головного потоку здійснюється через статичну властивість CurrentThread класу Thread:
class ThreadNaming { static void Main() { Thread.CurrentThread.Name = "main"; Thread worker = new Thread(Go); worker.Name = "worker"; worker.Start(); Go(); }
static void Go() { Console.WriteLine("Hello from " + Thread.CurrentThread.Name); } } |
Консольний виведення:
Hello from main Hello from worker |
Основні і фонові потоки
За замовчуванням потоки створюються як основні, що означає, що додаток не буде довершено, поки один з таких потоків буде виповнюватися. C# також підтримує фонові потоки, вони не продовжують життя додаткові, а завершуються відразу ж, як тільки всі основні потоки будуть довершені.
ПРИМІТКА Зміна статусу потоку з основного на фоновий не змінює його пріоритет або статус у планувальнику потоків. |
Статус потоку переключається з основного на фоновий за допомогою властивості IsBackground, як показано в наступному прикладі:
class PriorityTest { static void Main(string[] args) { Thread worker = new Thread(delegate() { Console.ReadLine(); });
if (args.Length > 0) worker.IsBackground = true;
worker.Start(); } } |
Якщо програма викликається без аргументів, робочий потік виконується за замовчуванням як основний потік і очікує на ReadLine, поки користувач не натисне Enter. Тим часом головний потік завершується, але додаток продовжує виповнюватися, тому що робочий потік ще живий.
Якщо ж програму запустити з аргументами командного рядка, робочий потік одержить статус фонового і програма завершиться практично відразу після завершення головного потоку, зі знищенням потоку, що очікує введення користувача за допомогою методу ReadLine.
Коли фоновий потік завершується таким способом, усі блоки finally усередині потоку ігноруються. Оскільки невиконання коду в finally звичайно небажано, буде правильно очікувати завершення усіх фонових потоків перед виходом із програми, призначивши потрібний таймаут (за допомогою Thread.Join). Якщо з якихось причин робочий потік не завершується за виділений час, можна спробувати аварийно завершити його (Thread.Abort), а якщо і це не вийде, дозволити вмерти йому разом із процесом (також не перешкодить записати інформацію про проблему в лог).
Перетворення робочого потоку у фоновий може бути останнім шансом завершити додаток, тому що не умираючий основний потік не дасть додаткові завершитися. Завислий основний потік особливо підступний у додатках Windows Forms, тому що додаток завершується, коли завершується його головний потік (принаймні, для користувача), але його процес продовжує виконуватися. У диспетчері задач воно зникне зі списку додатків, хоча ім'я його файлу, що виконується, залишиться в списку процесів, що виповнюються. Поки користувач не знайде і не приб'є його, процес продовжить споживати ресурси і, можливо, буде перешкоджати запускові або нормальному функціонуванню знову запущеного екземпляра додатка.
