Можно внутри лока (вместо Suspend'a) выставить какой-нибудь локальный флажок, а по выходе из лока поставить еще один if (<флажок>) Thread.CurrentThread.Suspend();
Здравствуйте, Аноним, Вы писали:
А>Шутки в сторону.
А>Объясните лучше как работает Monitor.Wait(object )
А>Может с ним удасться кашу сварить.
Так же, как и WaitHandle, только меньше жрет ресурсов.
Ну а если шутки в сторону, то давай и ты шутки в сторону и расскажи, почему у тебя возникла столь экзотичная необходимость. Под пристальным взглядом многоголового all может найтись и другое решение.
Re[4]: lock и Thread.Suspend
От:
Аноним
Дата:
18.08.04 07:16
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>Шутки в сторону.
А>>Объясните лучше как работает Monitor.Wait(object )
А>>Может с ним удасться кашу сварить.
A>Так же, как и WaitHandle, только меньше жрет ресурсов.
A>Ну а если шутки в сторону, то давай и ты шутки в сторону и расскажи, почему у тебя возникла столь экзотичная необходимость. Под пристальным взглядом многоголового all может найтись и другое решение.
Есть класс реализующий очередь заданий. Задания всегда выполняются последовательно друг за другом в одном потоке. А вот управление этой очередью (добавление заданий, удаление заданий и т.п.) может быть выполнено из различных потоков.
А вот и конкретная проблема: Если поток закончил выполнять задание, затем проверил cписок заданий и он пуст, тогда поток не уничтожается, а просто засыпает (suspend). Понятно, что при проверке списка заданий его нужно залочить, чтобы другой поток в это время не добавил новое задание.
Если поток разлочит список заданий, а только потом заснет, тогда есть шанс, что какой-то поток вставит задание, а поток исполнения его не подхватит, поскольку уже спит.
Аналогичная проблема, когда делаем Resumе для потока выполнения заданий.
Здравствуйте, Аноним, Вы писали:
А>Есть класс реализующий очередь заданий. Задания всегда выполняются последовательно друг за другом в одном потоке. А вот управление этой очередью (добавление заданий, удаление заданий и т.п.) может быть выполнено из различных потоков.
Как знакомо! Не далее как вчера делал то же самое. Но попроще, без удаления.
Итак, inter-thread communication:
Class ITC_class
Private _queue As New Collections.Queue
Private _wakeUp As New Threading.AutoResetEvent(False)
Private _endWork As Boolean
Public Sub Add(ByVal data As Data)
SyncLock Me._queue
Me._queue.Enqueue(data)
End SyncLock
Me._wakeUp.Set()
End Sub
Public Function GetData() As Data
Do
SyncLock Me._queue
With Me._queue
If .Count > 0 Then Return .Dequeue
End With
End SyncLock
Me._wakeUp.WaitOne()
Loop Until Me._endWork
Return Nothing
End Function
Public Sub EndWork()
Me._endWork = True
Me._wakeUp.Set()
End Sub
End Class
Class Data
' и тут все что хочешь :)End Class
Словами: внутри lock находится только операции с очередью — добавление, извлечение. Задания нет — выходим из lock и ждем на event-е. Сигнал дается другим потоком после добавления задания. Ну и дополнительная функция сигнала — выйти из ожидания, поскольку пора кончать работу (доп. флажок).
И последнее, очевидное
— GetData вызывается потоком, где выполняются задания
— Add вызывается потоком, добавляющий задания
— EndWork вызывается любым потоком для окончания работы потока с заданиями.
Здравствуйте, <Аноним>, Вы писали:
А>Есть класс реализующий очередь заданий. Задания всегда выполняются последовательно друг за другом в одном потоке. А вот управление этой очередью (добавление заданий, удаление заданий и т.п.) может быть выполнено из различных потоков.
А>А вот и конкретная проблема: Если поток закончил выполнять задание, затем проверил cписок заданий и он пуст, тогда поток не уничтожается, а просто засыпает (suspend).
Закат солнца вручную? Не проще ли воспользоваться пулом?