куємо чергу URL і дістаємо звідти одна адреса
lock (URLlocker)
{(URLs.Count == 0)
break ;//адрес більше немає, виходимо з методу, завершуємо потік
else = URLs.Dequeue ();
}. WriteLine (URL + "- start downloading ...");
// завантажуємо страніцуrequest = WebRequest.Create (URL); response = (HttpWebResponse) request.GetResponse (); HTML = (new StreamReader (response.GetResponseStream ())). ReadTo End ();
// блокуємо список викачаних сторінок, і заносимо туди свою сторінку
lock (HTMLlocker). Add (HTML);
//. WriteLine (URL + "- downloaded (" + HTML.Length + "bytes)");
}
}
}
}
Цей приклад - робочий, але в ньому немає таймера, вибору потоків, обробки помилок і контролю завершення потоків.
У наведеному прикладі ми створили три потоки. Стартовим методом для кожного потоку був метод Download (). Потік існує до тих пір, поки не виконається метод Download (). Як тільки цей метод завершується, завершується і потік. У цьому прикладі головний потік (той, який створює інші потоки) не очікує завершення дочірніх потоків і не відстежує їх завершення. Як тільки користувач натисне Enter в точці Console.ReadLine () ;), головний потік завершиться, а дочірні будуть продовжувати працювати, поки не буде вичерпана чергу адрес. Додаток завершиться тільки тоді, коли завершаться всі його потоки. p align="justify"> Для того, щоб зробити очікування завершення безлічі потоків з головного потоку створюємо масив прапорців, по одному прапорця на потік. Коли потік відпрацював - він встановлює свій прапорець. Головний потік в цей час чекає, поки всі прапорці будуть встановлені - і коли це відбувається - продовжує своє виконання. Для нашого прикладу програми скачування сайтів це буде виглядати так:
static void Main (string [] args)
{. Enqueue ("#" justify">// створюємо масив хендлеров, для контролю завершення потоків
ManualResetEvent [] handles = new ManualResetEvent [3];
// створюємо і запускаємо 3 потоку (int i = 0; i <3; i + +)
{[i] = new ManualResetEvent (false);
(new Thread (new ParameterizedThreadStart (Download))). Start (handles [i]);
}
// очікуємо, поки всі потоки отработают.WaitAll (handles);
//. WriteLine ("Download completed");. ReadLine ();
} static void Download (object handle)
{
// будемо крутити цикл, поки не закінчаться ULR в черзі (true)
{
...
<...