Как приостановтиь/возобновить выполнение потока ???
От: Cynic Россия  
Дата: 19.05.08 12:31
Оценка:
Как лучше приостанавливать и возобновлять выполнение потока? Пытался использовать Suspend и Resume, но Suspend в ряде случаев приостанавливает выполнение не только того потока которого надо, но ещё вешает и основной! В общем то мне надо создать поток в конструкторе и тут же его приостановить, до тех пор пока он не понадобиться. Какие классы лучше использовать в такой ситуации
:)
Re: Как приостановтиь/возобновить выполнение потока ???
От: nikov США http://www.linkedin.com/in/nikov
Дата: 19.05.08 12:39
Оценка: 1 (1) +1
Здравствуйте, Cynic, Вы писали:

C> Какие классы лучше использовать в такой ситуации


Поток должен добровольно ждать некоторого события (например, ManualResetEvent). С приостановкой потока снаружи легко нарваться на дедлок.
Re: Как приостановтиь/возобновить выполнение потока ???
От: Kore Sar  
Дата: 19.05.08 12:40
Оценка:
Здравствуйте, Cynic, Вы писали:

C> Как лучше приостанавливать и возобновлять выполнение потока? Пытался использовать Suspend и Resume, но Suspend в ряде случаев приостанавливает выполнение не только того потока которого надо, но ещё вешает и основной! В общем то мне надо создать поток в конструкторе и тут же его приостановить, до тех пор пока он не понадобиться. Какие классы лучше использовать в такой ситуации


Либо вы неправильно пользовали Suspend (здесь
Автор(ы): Joseph Albahari
Дата: 24.03.2007
Подробно рассматривается работа с потоками — запуск, завершение, прерывание, блокировки, синхронизация, контексты синхронизации, особенности взаимодействия с апартаментами, а также потоковые возможности .NET — потоковые таймеры, пулы потоков, BackgroundWorker, асинхронные методы и делегаты.
В статье использован материал из книги Joseph Albahari, Ben Albahari "C# 3.0 in a Nutshell" — http://www.oreilly.com/catalog/9780596527570/
и здесь
Автор(ы): Joseph Albahari
Дата: 27.06.2007
Окончание статьи, опубликованной в RSDN Magazine #1-2007. Рассматриваются особенности взаимодействия с апартаментами, потоковые таймеры, пулы потоков, BackgroundWorker, асинхронные методы и делегаты.
В статье использован материал из книги Joseph Albahari, Ben Albahari "C# 3.0 in a Nutshell" — http://www.oreilly.com/catalog/9780596527570/
), либо просто не создавайте поток, пока он не понадобился.
Re: Как приостановтиь/возобновить выполнение потока ???
От: cencio Украина http://ua-coder.blogspot.com
Дата: 19.05.08 12:41
Оценка:
Здравствуйте, Cynic, Вы писали:

C> Как лучше приостанавливать и возобновлять выполнение потока? Пытался использовать Suspend и Resume, но Suspend в ряде случаев приостанавливает выполнение не только того потока которого надо, но ещё вешает и основной! В общем то мне надо создать поток в конструкторе и тут же его приостановить, до тех пор пока он не понадобиться. Какие классы лучше использовать в такой ситуации


в описаном случае нужно создавать "спящий" поток, в обычном винапи это делается указанием флажка CREATE_SUSPENDED
http://msdn.microsoft.com/en-us/library/ms682453(VS.85).aspx

в дотнете тоже должна быть такая возможность.
Re: Как приостановтиь/возобновить выполнение потока ???
От: pt4h Беларусь http://dzmitryhuba.blogspot.com/
Дата: 19.05.08 12:46
Оценка:
Здравствуйте, Cynic, Вы писали:

C> Как лучше приостанавливать и возобновлять выполнение потока? Пытался использовать Suspend и Resume, но Suspend в ряде случаев приостанавливает выполнение не только того потока которого надо, но ещё вешает и основной! В общем то мне надо создать поток в конструкторе и тут же его приостановить, до тех пор пока он не понадобиться. Какие классы лучше использовать в такой ситуации


Не стоит пользоваться Suspend и Resume

Do not use the Suspend and Resume methods to synchronize the activities of threads. You have no way of knowing what code a thread is executing when you suspend it. If you suspend a thread while it holds locks during a security permission evaluation, other threads in the AppDomain might be blocked. If you suspend a thread while it is executing a class constructor, other threads in the AppDomain that attempt to use that class are blocked. Deadlocks can occur very easily.


Используйте примитивы синхронизации. Например ManualResetEvent:
Re: Как приостановтиь/возобновить выполнение потока ???
От: -DIS-  
Дата: 19.05.08 13:12
Оценка: 19 (3)
Здравствуйте, Cynic, Вы писали:

C> Как лучше приостанавливать и возобновлять выполнение потока? Пытался использовать Suspend и Resume, но Suspend в ряде случаев приостанавливает выполнение не только того потока которого надо, но ещё вешает и основной! В общем то мне надо создать поток в конструкторе и тут же его приостановить, до тех пор пока он не понадобиться. Какие классы лучше использовать в такой ситуации


Suspend и Resume действительно лучше не использовать, как уже писали.

Советую не создавать потоки вручную, а пользоваться ThreadPool. Когда понадобиться выполнить операцию в другом потоке, делайте

ThreadPool.QueueUserWorkItem(MethodToDo);

В пуле есть до 25-ти спящих потоков по умолчанию. Он возьмет любой и выполнит ваш делегат в этом потоке. Плюсы этого дела — не создаеться новый поток, используются уже готовые. Если в пуле потоки будут заканчиваться, он сам создаст когда надо будет. Останавливать поток тож ненадо. Просто пусть он отработает и "уснет". Когда надо будет возобновить, делайте заново ThreadPool.QueueUserWorkItem
Re: Как приостановтиь/возобновить выполнение потока ???
От: chaynik_  
Дата: 19.05.08 13:30
Оценка: :))
Здравствуйте, Cynic, Вы писали:

C> Как лучше приостанавливать и возобновлять выполнение потока? Пытался использовать Suspend и Resume, но Suspend в ряде случаев приостанавливает выполнение не только того потока которого надо, но ещё вешает и основной! В общем то мне надо создать поток в конструкторе и тут же его приостановить, до тех пор пока он не понадобиться. Какие классы лучше использовать в такой ситуации


если точно известро время, на которое надо остановить поток, можно использовать Thread.Sleep(x) x — время ожидания
Re[2]: Как приостановтиь/возобновить выполнение потока ???
От: Cynic Россия  
Дата: 19.05.08 13:35
Оценка:
Здравствуйте, -DIS-, Вы писали:

DIS>Советую не создавать потоки вручную, а пользоваться ThreadPool. Когда понадобиться выполнить операцию в другом потоке, делайте


DIS>ThreadPool.QueueUserWorkItem(MethodToDo);


DIS>В пуле есть до 25-ти спящих потоков по умолчанию. Он возьмет любой и выполнит ваш делегат в этом потоке. Плюсы этого дела — не создаеться новый поток, используются уже готовые. Если в пуле потоки будут заканчиваться, он сам создаст когда надо будет. Останавливать поток тож ненадо. Просто пусть он отработает и "уснет". Когда надо будет возобновить, делайте заново ThreadPool.QueueUserWorkItem


Cитуация такая. Поток используется для того, чтобы с определённым промежутком вызывать метод Refresh() для контрола, т.к. он может вращаться и его нужно постоянно перерисовывать. Перерисовка по идее должна происходить до тех пор пока контрол не прекратит своё существование! Вообще при выполнении конструктора контрола выбирается стиль по-умолчанию, которому выполнение потока не нужно. И есть два свойства от которых зависит когда начнётся или остановиться выполнение потока. Я изначально хотел создать поток в конструкторе, запустить его и тут же приостановить, но как уже и писали такой вариант может привести к deadlock. Поэтому я решил в каждом случае создавать и уничтожать этот поток, но есть сомнения на счёт производительности. Поскольку этот поток используется для перерисовки контрола, производительность не самое последнее дело! Насколько вообще длительная операция создание/уничтожение потока
Про ThreadPool слышал, но ни когда его ни юзал. Если например делегат потока называется _rotateThread, то как его запускать/останавливать используя ThreadPool
:)
Re[3]: Как приостановтиь/возобновить выполнение потока ???
От: Schade Россия  
Дата: 19.05.08 13:55
Оценка:
Здравствуйте, Cynic, Вы писали:

C> Cитуация такая. Поток используется для того, чтобы с определённым промежутком вызывать метод Refresh() для контрола, т.к. он может вращаться и его нужно постоянно перерисовывать.


Тогда тебе поток вообще не нужен. Обращения к контролам должны происходить в контексте того же потока, в котором они созданы. Все вызовы из других потоков должны происходить через вызов Control.Invoke, что никоим образом не лучше и не производительнее, чем банальный таймер.
Re[3]: Как приостановтиь/возобновить выполнение потока ???
От: -DIS-  
Дата: 19.05.08 14:11
Оценка:
Здравствуйте, Cynic, Вы писали:

C> Cитуация такая. Поток используется для того, чтобы с определённым промежутком вызывать метод Refresh()

C> Про ThreadPool слышал, но ни когда его ни юзал. Если например делегат потока называется _rotateThread, то как его запускать/останавливать используя ThreadPool

Тогда бери и делай таймер. Я для таких целей использовал System.Timers.Timer

Кстати, он работает как раз в пуле потоков (в том же thread что и сам ThreadPool). В обработчике надо будет делать Invoke/BeginInvoke для того, чтоб сделать рефреш именно в главном потоке.
Вот пример:
По анологии можешь сделать в своем контроле

    public partial class Form2 : Form
    {
        protected System.Timers.Timer m_Timer;

        public Form2()
        {
            InitializeComponent();
            m_Timer = new System.Timers.Timer();
            m_Timer.AutoReset = true;
            m_Timer.Interval = 500; // ms
            m_Timer.Elapsed += new System.Timers.ElapsedEventHandler(m_Timer_Elapsed);
            m_Timer.Start(); // запустишь его конда надо будет
        }

        void m_Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (InvokeRequired)
            {
                this.BeginInvoke(new System.Timers.ElapsedEventHandler(m_Timer_Elapsed)
                    , new object[] { sender, e });

                return; // в этом побочном потоке ничего не делаем больше
            }

            Refresh();
        }

    }
Re[2]: Как приостановтиь/возобновить выполнение потока ???
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 19.05.08 14:15
Оценка: +2
Здравствуйте, -DIS-, Вы писали:

DIS>Советую не создавать потоки вручную, а пользоваться ThreadPool. Когда понадобиться выполнить операцию в другом потоке, делайте


DIS>ThreadPool.QueueUserWorkItem(MethodToDo);


Вредный совет — использовать или нет пул зависит от задачи.
... <<RSDN@Home 1.2.0 alpha 4 rev. 1082 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[4]: Как приостановтиь/возобновить выполнение потока ???
От: Schade Россия  
Дата: 19.05.08 14:51
Оценка: +2
Здравствуйте, -DIS-, Вы писали:


DIS>Тогда бери и делай таймер. Я для таких целей использовал System.Timers.Timer

DIS>Кстати, он работает как раз в пуле потоков (в том же thread что и сам ThreadPool). В обработчике надо будет делать Invoke/BeginInvoke для того, чтоб сделать рефреш именно в главном потоке.

А если взять System.Windows.Forms.Timer, то и маршаллить вызов через Invoke не надо
Re[5]: Как приостановтиь/возобновить выполнение потока ???
От: -DIS-  
Дата: 19.05.08 15:06
Оценка:
Здравствуйте, Schade, Вы писали:

S>А если взять System.Windows.Forms.Timer, то и маршаллить вызов через Invoke не надо


Угу, тогда тот же самый инвок будет дергаться внутри того таймера.. экономия — только в паре строк кода..
Re[6]: Как приостановтиь/возобновить выполнение потока ???
От: Cynic Россия  
Дата: 19.05.08 15:23
Оценка:
Здравствуйте, -DIS-, Вы писали:

DIS>Здравствуйте, Schade, Вы писали:


S>>А если взять System.Windows.Forms.Timer, то и маршаллить вызов через Invoke не надо


DIS>Угу, тогда тот же самый инвок будет дергаться внутри того таймера.. экономия — только в паре строк кода...


Т.е. System.Windows.Forms.Timer все равно реализуется с использованием потоков?
:)
Re[7]: Как приостановтиь/возобновить выполнение потока ???
От: Schade Россия  
Дата: 19.05.08 15:30
Оценка: -1
Здравствуйте, Cynic, Вы писали:

C>Т.е. System.Windows.Forms.Timer все равно реализуется с использованием потоков?


Ну да. Что ж ему, бесконечный цикл крутить, отнимая все время CPU? Просто позволяет не морочиться с организацией межпоточного взаимодействия.
Re[8]: Как приостановтиь/возобновить выполнение потока ???
От: Cynic Россия  
Дата: 19.05.08 15:35
Оценка:
Здравствуйте, Schade, Вы писали:

S>Здравствуйте, Cynic, Вы писали:


C>>Т.е. System.Windows.Forms.Timer все равно реализуется с использованием потоков?


S>Ну да. Что ж ему, бесконечный цикл крутить, отнимая все время CPU? Просто позволяет не морочиться с организацией межпоточного взаимодействия.


Самое смешное, что я день потратил, чтобы процедуру обновления окна обкатать, а про Timer совсем забыл, хотя сам в книге жирно-о-о подчеркнул, мол пригодится
:)
Re[8]: Как приостановтиь/возобновить выполнение потока ???
От: arkhivania  
Дата: 19.05.08 19:03
Оценка:
Здравствуйте, Schade, Вы писали:

S>Здравствуйте, Cynic, Вы писали:


C>>Т.е. System.Windows.Forms.Timer все равно реализуется с использованием потоков?


S>Ну да. Что ж ему, бесконечный цикл крутить, отнимая все время CPU? Просто позволяет не морочиться с организацией межпоточного взаимодействия.


System.Windows.Forms.Timer не использует другие потоки, а работает по стратегии Win32 API Timer. Этот таймер работает в очереди события и про что важно не забывать, что если есть другие "более важные" события, то таймеровские события откладываются до более хорошего времени. System.Windows.Forms.Timer — самое оно для вашей задачи. Очень полезно у этого таймера использовать то свойство, что его можно перезапускать, то есть если вызвать подряд Stop и сразу Start, то следующий тик произойдет через Time Interval заданный в свойстве таймера.
Re[9]: Как приостановтиь/возобновить выполнение потока ???
От: Schade Россия  
Дата: 19.05.08 19:38
Оценка:
Здравствуйте, arkhivania, Вы писали:

A>System.Windows.Forms.Timer не использует другие потоки, а работает по стратегии Win32 API Timer...

Да понятно, что там просто вызов АПИшного SetTimer со всеми вытекающими (через message pump). Тут смысл даже не в деталях, а в том, что хоть с таймером в другом потоке, хоть с использованием WinAPI Timer все равно получается работа на основе событий вместо задуманного Cynic'ом цикла в отдельном потоке.

A>System.Windows.Forms.Timer — самое оно для вашей задачи...

Это не моя задача — это к Cynic'у
Re[9]: Как приостановтиь/возобновить выполнение потока ???
От: Cynic Россия  
Дата: 19.05.08 21:10
Оценка:
Здравствуйте, arkhivania, Вы писали:

A>System.Windows.Forms.Timer не использует другие потоки, а работает по стратегии Win32 API Timer. Этот таймер работает в очереди события и про что важно не забывать, что если есть другие "более важные" события, то таймеровские события откладываются до более хорошего времени. System.Windows.Forms.Timer — самое оно для вашей задачи. Очень полезно у этого таймера использовать то свойство, что его можно перезапускать, то есть если вызвать подряд Stop и сразу Start, то следующий тик произойдет через Time Interval заданный в свойстве таймера.


Попробовал использовать таймер. И похоже в моем случае "более важных" событий действительно много Вместо 10 раз в секунду, таймер срабатывает раза 2-3! А мне нужно, чтобы ни смотря ни на что, метод выполнялся 10 раз в секунду. С потоками такое получается на ура. Может я чего про таймер не знаю
:)
Re[10]: Как приостановтиь/возобновить выполнение потока ???
От: Cynic Россия  
Дата: 19.05.08 22:48
Оценка:
Здравствуйте, Cynic, Вы писали:

C>Здравствуйте, arkhivania, Вы писали:


Этот таймер работает в очереди события и про что важно не забывать, что если есть другие "более важные" события, то таймеровские события откладываются до более хорошего времени.

А можно таймеровские события сделать "самыми важными"
:)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.