:: Меню ::

Головна
  • Про сайт
  • Введення
  • Середовище програмування VB .NET: Visual Studio .NET
  • Вирази, оператори і передача управління
  • Класи і об'єкти
  •  Спадкоємство і інтерфейси
  • Обробка подій і делегати
  • Обробка помилок в VB .NET
  • Форми Windows, графічний вивід і друк
  • Уведення-виведення
  •  Багатопотокові застосування
  • Підтримка баз-даних в VB .NET
  • Короткий огляд ASP .NET
  • Складки .NET, установка додатків і COM Interop
  • Книга для гостей
    Контакти
    Добавити у вибране

    :: Друзі ::

     
     

    :: Лічильники ::

    = =

     

     

     

     

    Метод Join

    Іноді програмний потік потрібно припинити до моменту завершення іншого потоку. Допустимо, ви хочете припинити потік 1 до тих пір, поки потік 2 не завершить свої обчислення. Для цього з потоку 1 викликається метод Join для потоку 2. Інакше кажучи, команда

    thread2.Join()

    припиняє поточний потік і чекає завершення потоку 2. Потік 1 переходить в заблокований стан.

    Якщо приєднати потік 1 до потоку 2 методом Join, операційна система автоматично запустить потік 1 після завершення потоку 2. Врахуйте, що процес запуску є недетермінованим: не можна точно сказати, через який проміжок часу після завершення потоку 2 запрацює потік 1. Існує і інша версія Join, яка повертає логічну величину:

    thread2.Join(Integer)

    Цей метод або чекає завершення потоку 2, або розблоковує потік 1 після закінчення заданого інтервалу часу, унаслідок чого планувальник операційної системи знову виділятиме потоку процесорний час. Метод повертає True, якщо потік 2 завершується до закінчення заданого інтервалу тайм-ауту, і False інакше.

    Не забувайте основне правило: незалежно тому, чи завершився потік 2 або про-ізошел тайм-аут, ви не можете управляти моментом активізації потоку 1.

    Імена потоків, Currentthread і Threadstate

    Перед запуском кожному потоку рекомендується привласнити змістовне ім'я, оскільки імена значно спрощують відладку багатопотокових програм. Для цього слід задати значення властивості Name командою наступного вигляду:

    bthread.Name = "Subtracting thread"

    Властивість Thread.CurrentThread повертає посилання на об'єкт потоку, що виконується зараз.

    Хоча для відладки багатопотокових застосувань в VB .NET існує чудове вікно потоків, про яке розказано далі, нас дуже часто виручала команда

    Msgbox(Thread.CurrentThread.Name)

    Нерідко з'ясовувалося, що код виконується зовсім не в тому потоці, в якому йому належало виконуватися.

    Нагадаємо, що термін «недетерміноване планування програмних потоків» означає дуже просту річ: у розпорядженні програміста практично немає засобів, що дозволяють впливати на роботу планувальника. З цієї причини в програмах часто використовується властивість Threadstate, що повертає інформацію про поточний стан потоку.

    Вікно потоків

    Вікно потоків (Threads window) Visual Studio .NET надає неоціниму допомогу у відладці багатопотокових програм. Воно активізується командою підміню Debug > Windows в режимі переривання. Допустимо, ви призначили ім'я потоку bthread наступною командою:

    bthread.Name = "Subtracting thread"

    Зразковий вид вікна потоків після переривання програми комбінацією клавіш Ctrl+break (або іншим способом) показаний на мал. 10.5.

    Мал. 10.5. Вікно потоків

    Стрілкою в першому стовпці позначається активний потік, повертаний властивістю Thread.CurrentThread. Стовпець ID містить числові ідентифікатори потоків. У наступному стовпці перераховані імена потоків (якщо вони були привласнені). Стовпець Location указує виконувану процедуру (наприклад, процедура Writeline класу Console на мал. 10.5). Решта стовпців містить інформацію про пріоритет і припинені потоки (див. наступний розділ).

    Вікно потоків (а не операційна система!) дозволяє управляти потоками вашої програми за допомогою контекстних меню. Наприклад, ви можете зупинити поточний потік, для чого слід клацнути у відповідному рядку правою кнопкою миші і вибрати команду Freeze (пізніше роботу зупиненого потоку можна відновити). Зупинка потоків часто використовувана при відладці, щоб неправильно працюючий потік не заважав роботі додатку. Крім того, вікно потоків дозволяє активізувати інший (не зупинений) потік; для цього слід клацнути правою кнопкою миші в потрібному рядку і вибрати в контекстному меню команду Switch To Thread (або просто зробити подвійне клацання на рядку потоку). Як буде показано далі, це дуже зручно при діагностиці потенційних взаємних блокувань (deadlocks).

    Припинення потоку

    Тимчасово невживані потоки можна перевести в пасивний стан методом Slєєр. Пасивний потік також вважається за заблокований. Зрозуміло, з перекладом потоку в пасивний стан на долю решти потоків дістанеться більше ресурсів процесора. Стандартний синтаксис методу Slєєр виглядає таким чином: Thread.Sleep(інтервал_в_міллісекундах)

    В результаті виклику Sleep активний потік переходить в пасивний стан як мінімум на задану кількість мілісекунд (втім, активізація відразу ж після закінчення заданого інтервалу не гарантується). Звернете увагу: при виклику методу посилання на конкретний потік не передається — метод Sleep викликається тільки для активного потоку.

    Інша версія Sleep примушує поточний потік поступитися частиною виділеного процесорного часу, що залишилася:

    Thread.Sleep(0)

    Наступний варіант переводить поточний потік в пасивний стан на необмежений час (активізація відбувається тільки при виклику Interrupt):

    Thread.Slеер(Timeout.Infinite)

    Оскільки пасивні потоки (навіть при необмеженому часі очікування) можуть уриватися методом Interrupt, що приводить до ініціації виключення Threadlnterruptexcepti on, виклик Slєєр завжди полягає в блок Try-catch, як в наступному фрагменті:

    Try

    Thread.Sleep(200)

    Catch tie As Threadlnterruptedexception

    ' Пасивний стан потоку був перерваний

    Catch e As Exception

    'Решта виключень

    End Try

    Кожна програма .NET працює в програмному потоці, тому метод Sleep також використовується для припинення роботи програм (якщо простір імен Threadipg не імпортується програмою, доводиться використовувати повне ім'я Threading.Thread. Sleep).

    Завершення або переривання програмних потоків

    Потік автоматично завершується при виході з методу, вказаного при створенні делегата Threadstart, але іноді потрібно завершити метод (отже, і потік) при виникненні певних чинників. У таких випадках в потоках зазвичай перевіряється умовна змінна, залежно від стану якої ухвалюється рішення про аварійний вихід з потоку. Як правило, для цього в процедуру включається цикл Do-while:

    Sub Threadedmethod()

    ' У програмі необхідно передбачити засоби для опиту

    ' умовною змінною.

    ' Наприклад, умовну змінну можна оформити у вигляді властивості

    ' і використовувати посилання на цю властивість в програмі.

    Do While conditionvariable = False And Moreworktodo

    ' Основний код

    Loop End Sub

    На опит умовної змінної йде якийсь час. Постійний опит в умові циклу слід використовувати лише в тому випадку, якщо ви чекаєте передчасного завершення потоку.

    Якщо перевірка умовної змінної повинна відбуватися в строго певному місці, скористайтеся командою If-then у поєднанні з Exit Sub усередині нескінченного циклу.

    Доступ до умовної змінної необхідно синхронізувати, щоб дія з боку інших потоків не перешкодила її нормальному використанню. Етой важливій темі присвячений розділ «Вирішення проблеми: синхронізація».

    На жаль, код пасивних (або заблокованих іншим чином) потоків не виконується, тому варіант з опитом умовної змінної для них не підходить. В цьому випадку слід викликати метод Interrupt для об'єктної змінної, що містить посилання на потрібний потік.

    Метод Interrupt може викликатися тільки для потоків, що знаходяться в стані Wait, Sleep або Join. Якщо викликати Interrupt для потоку, що знаходиться в одному з перерахованих станів, то через деякий час потік знову почне працювати, а виконавче середовище ініціює в потоці виключення Threadlnterruptedexcepti on. Це відбувається навіть в тому випадку, якщо потік був переведений в пасивний стан на невизначений термін викликом Thread.Sleepdimeout. Infinite). Ми говоримо «через деякий час», оскільки планування потоків має недетерміновану природу. Виключення Threadlnterruptedexcepti on перехоплюється секцією Catch, що містить код виходу із стану очікування. Проте секція Catch зовсім не зобов'язана завершувати потік по виклику Interrupt — потік обробляє виключення на свій розсуд.

    У.NET метод Interrupt може викликатися навіть для незаблокованих потоків. В цьому випадку потік уривається при найближчому блокуванні.

     




    :: Наша кнопка ::

    Отримати код:

    Підтримайте наш сайт і розмістіть нашу кнопку на своєму ресурсі.


    :: Реклама ::

    Скачати безкоштовно програму Microsoft Front Page 2003


    :: Посилання ::

    -


     

     

     


    Copyright ©