Как лучше приостанавливать и возобновлять выполнение потока? Пытался использовать Suspend и Resume, но Suspend в ряде случаев приостанавливает выполнение не только того потока которого надо, но ещё вешает и основной! В общем то мне надо создать поток в конструкторе и тут же его приостановить, до тех пор пока он не понадобиться. Какие классы лучше использовать в такой ситуации
:)
Re: Как приостановтиь/возобновить выполнение потока ???
Здравствуйте, Cynic, Вы писали:
C> Как лучше приостанавливать и возобновлять выполнение потока? Пытался использовать Suspend и Resume, но Suspend в ряде случаев приостанавливает выполнение не только того потока которого надо, но ещё вешает и основной! В общем то мне надо создать поток в конструкторе и тут же его приостановить, до тех пор пока он не понадобиться. Какие классы лучше использовать в такой ситуации
Здравствуйте, Cynic, Вы писали:
C> Как лучше приостанавливать и возобновлять выполнение потока? Пытался использовать Suspend и Resume, но Suspend в ряде случаев приостанавливает выполнение не только того потока которого надо, но ещё вешает и основной! В общем то мне надо создать поток в конструкторе и тут же его приостановить, до тех пор пока он не понадобиться. Какие классы лучше использовать в такой ситуации
Здравствуйте, 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: Как приостановтиь/возобновить выполнение потока ???
Здравствуйте, Cynic, Вы писали:
C> Как лучше приостанавливать и возобновлять выполнение потока? Пытался использовать Suspend и Resume, но Suspend в ряде случаев приостанавливает выполнение не только того потока которого надо, но ещё вешает и основной! В общем то мне надо создать поток в конструкторе и тут же его приостановить, до тех пор пока он не понадобиться. Какие классы лучше использовать в такой ситуации
Suspend и Resume действительно лучше не использовать, как уже писали.
Советую не создавать потоки вручную, а пользоваться ThreadPool. Когда понадобиться выполнить операцию в другом потоке, делайте
ThreadPool.QueueUserWorkItem(MethodToDo);
В пуле есть до 25-ти спящих потоков по умолчанию. Он возьмет любой и выполнит ваш делегат в этом потоке. Плюсы этого дела — не создаеться новый поток, используются уже готовые. Если в пуле потоки будут заканчиваться, он сам создаст когда надо будет. Останавливать поток тож ненадо. Просто пусть он отработает и "уснет". Когда надо будет возобновить, делайте заново ThreadPool.QueueUserWorkItem
Re: Как приостановтиь/возобновить выполнение потока ???
Здравствуйте, Cynic, Вы писали:
C> Как лучше приостанавливать и возобновлять выполнение потока? Пытался использовать Suspend и Resume, но Suspend в ряде случаев приостанавливает выполнение не только того потока которого надо, но ещё вешает и основной! В общем то мне надо создать поток в конструкторе и тут же его приостановить, до тех пор пока он не понадобиться. Какие классы лучше использовать в такой ситуации
если точно известро время, на которое надо остановить поток, можно использовать Thread.Sleep(x) x — время ожидания
Re[2]: Как приостановтиь/возобновить выполнение потока ???
Здравствуйте, -DIS-, Вы писали:
DIS>Советую не создавать потоки вручную, а пользоваться ThreadPool. Когда понадобиться выполнить операцию в другом потоке, делайте
DIS>ThreadPool.QueueUserWorkItem(MethodToDo);
DIS>В пуле есть до 25-ти спящих потоков по умолчанию. Он возьмет любой и выполнит ваш делегат в этом потоке. Плюсы этого дела — не создаеться новый поток, используются уже готовые. Если в пуле потоки будут заканчиваться, он сам создаст когда надо будет. Останавливать поток тож ненадо. Просто пусть он отработает и "уснет". Когда надо будет возобновить, делайте заново ThreadPool.QueueUserWorkItem
Cитуация такая. Поток используется для того, чтобы с определённым промежутком вызывать метод Refresh() для контрола, т.к. он может вращаться и его нужно постоянно перерисовывать. Перерисовка по идее должна происходить до тех пор пока контрол не прекратит своё существование! Вообще при выполнении конструктора контрола выбирается стиль по-умолчанию, которому выполнение потока не нужно. И есть два свойства от которых зависит когда начнётся или остановиться выполнение потока. Я изначально хотел создать поток в конструкторе, запустить его и тут же приостановить, но как уже и писали такой вариант может привести к deadlock. Поэтому я решил в каждом случае создавать и уничтожать этот поток, но есть сомнения на счёт производительности. Поскольку этот поток используется для перерисовки контрола, производительность не самое последнее дело! Насколько вообще длительная операция создание/уничтожение потока
Про ThreadPool слышал, но ни когда его ни юзал. Если например делегат потока называется _rotateThread, то как его запускать/останавливать используя ThreadPool
:)
Re[3]: Как приостановтиь/возобновить выполнение потока ???
Здравствуйте, Cynic, Вы писали:
C> Cитуация такая. Поток используется для того, чтобы с определённым промежутком вызывать метод Refresh() для контрола, т.к. он может вращаться и его нужно постоянно перерисовывать.
Тогда тебе поток вообще не нужен. Обращения к контролам должны происходить в контексте того же потока, в котором они созданы. Все вызовы из других потоков должны происходить через вызов Control.Invoke, что никоим образом не лучше и не производительнее, чем банальный таймер.
Re[3]: Как приостановтиь/возобновить выполнение потока ???
Здравствуйте, 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]: Как приостановтиь/возобновить выполнение потока ???
Здравствуйте, -DIS-, Вы писали:
DIS>Советую не создавать потоки вручную, а пользоваться ThreadPool. Когда понадобиться выполнить операцию в другом потоке, делайте
DIS>ThreadPool.QueueUserWorkItem(MethodToDo);
Вредный совет — использовать или нет пул зависит от задачи.
... <<RSDN@Home 1.2.0 alpha 4 rev. 1082 on Windows Vista 6.0.6001.65536>>
DIS>Тогда бери и делай таймер. Я для таких целей использовал System.Timers.Timer DIS>Кстати, он работает как раз в пуле потоков (в том же thread что и сам ThreadPool). В обработчике надо будет делать Invoke/BeginInvoke для того, чтоб сделать рефреш именно в главном потоке.
А если взять System.Windows.Forms.Timer, то и маршаллить вызов через Invoke не надо
Re[5]: Как приостановтиь/возобновить выполнение потока ???
Здравствуйте, -DIS-, Вы писали:
DIS>Здравствуйте, Schade, Вы писали:
S>>А если взять System.Windows.Forms.Timer, то и маршаллить вызов через Invoke не надо
DIS>Угу, тогда тот же самый инвок будет дергаться внутри того таймера.. экономия — только в паре строк кода...
Т.е. System.Windows.Forms.Timer все равно реализуется с использованием потоков?
:)
Re[7]: Как приостановтиь/возобновить выполнение потока ???
Здравствуйте, Schade, Вы писали:
S>Здравствуйте, Cynic, Вы писали:
C>>Т.е. System.Windows.Forms.Timer все равно реализуется с использованием потоков?
S>Ну да. Что ж ему, бесконечный цикл крутить, отнимая все время CPU? Просто позволяет не морочиться с организацией межпоточного взаимодействия.
Самое смешное, что я день потратил, чтобы процедуру обновления окна обкатать, а про Timer совсем забыл, хотя сам в книге жирно-о-о подчеркнул, мол пригодится
:)
Re[8]: Как приостановтиь/возобновить выполнение потока ???
Здравствуйте, 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]: Как приостановтиь/возобновить выполнение потока ???
Здравствуйте, arkhivania, Вы писали:
A>System.Windows.Forms.Timer не использует другие потоки, а работает по стратегии Win32 API Timer...
Да понятно, что там просто вызов АПИшного SetTimer со всеми вытекающими (через message pump). Тут смысл даже не в деталях, а в том, что хоть с таймером в другом потоке, хоть с использованием WinAPI Timer все равно получается работа на основе событий вместо задуманного Cynic'ом цикла в отдельном потоке.
A>System.Windows.Forms.Timer — самое оно для вашей задачи...
Это не моя задача — это к Cynic'у
Re[9]: Как приостановтиь/возобновить выполнение потока ???
Здравствуйте, arkhivania, Вы писали:
A>System.Windows.Forms.Timer не использует другие потоки, а работает по стратегии Win32 API Timer. Этот таймер работает в очереди события и про что важно не забывать, что если есть другие "более важные" события, то таймеровские события откладываются до более хорошего времени. System.Windows.Forms.Timer — самое оно для вашей задачи. Очень полезно у этого таймера использовать то свойство, что его можно перезапускать, то есть если вызвать подряд Stop и сразу Start, то следующий тик произойдет через Time Interval заданный в свойстве таймера.
Попробовал использовать таймер. И похоже в моем случае "более важных" событий действительно много Вместо 10 раз в секунду, таймер срабатывает раза 2-3! А мне нужно, чтобы ни смотря ни на что, метод выполнялся 10 раз в секунду. С потоками такое получается на ура. Может я чего про таймер не знаю
:)
Re[10]: Как приостановтиь/возобновить выполнение потока ???
Здравствуйте, Cynic, Вы писали:
C>Здравствуйте, arkhivania, Вы писали:
Этот таймер работает в очереди события и про что важно не забывать, что если есть другие "более важные" события, то таймеровские события откладываются до более хорошего времени.
А можно таймеровские события сделать "самыми важными"