РЕДАКТИРОВАТЬ : Мне слишком поздно пришло в голову (?), Что весь код, который я разместил в своем первом обновлении этого вопроса, был слишком большим для большинства читателей. Я на самом деле пошел вперед и написал пост в блоге на эту тему для всех, кто хочет его прочитать.
А пока я оставил исходный вопрос на месте, чтобы кратко взглянуть на проблему, которую я хотел бы решить.
Я также просто отмечу, что код, который я разместил (в своем блоге), до сих пор довольно хорошо выдерживал тестирование. Но я все еще интересуюсь любыми отзывами, которые люди хотят дать мне о том, насколько он чист / надежен / эффективен.
* Мне нравится, как это слово на самом деле не означает, что мы думаем , но мы, разработчики, используем его все время.
Оригинальный вопрос
Извините за смутное название вопроса - не уверен, как кратко изложить то, что я спрашиваю ниже. (Если кто-то с правами на редактирование может придумать более описательный заголовок, смело меняйте его.)
Мне нужно такое поведение. Я предполагаю рабочий класс, который принимает одну делегатскую задачу в своем конструкторе (для простоты я бы сделал его неизменным - больше задач не может быть добавлено после создания экземпляра). Я назову эту задачу T
. Класс должен иметь простой метод, например, GetToWork
, который будет демонстрировать такое поведение:
- Если работник не в данный момент работает
T
, то он начнет делать это прямо сейчас.
- Если рабочий является , в настоящий момент работающим
T
, то после его завершения он сразу же начнет T
.
GetToWork
можно вызывать любое количество раз, пока рабочий работает T
; простое правило состоит в том, что во время любого выполнения T
, если GetToWork
был вызван хотя бы один раз, , T
будет запущен снова после завершения (и затем, если GetToWork
вызывается при T
работает это время, оно повторится снова и т. д.).
Теперь, это довольно просто с булевым переключателем. Но этот класс должен быть поточно-ориентированным , и я имею в виду, что вышеприведенные шаги 1 и 2 должны включать атомарные операции (по крайней мере, я так думаю).
Добавлен слой сложности. Мне нужен класс "цепочки рабочих", который будет состоять из многих из этих рабочих, связанных вместе. Как только первый рабочий завершает работу, он по существу вызывает GetToWork
для рабочего после it; Между тем, если вызывается его собственный GetToWork
, он также перезапускается. Логический вызов GetToWork
в цепочке по сути аналогичен вызову GetToWork
в первом работнике в цепочке (я бы полностью хотел, чтобы работники цепочки не были публично доступны) .
Один из способов представить, как поведет себя эта гипотетическая «цепочка рабочих», - это сравнить ее с командой в эстафете. Предположим, есть четыре бегуна, от W1
до W4
, и пусть цепочка будет называться C
. Если я позвоню C.StartWork()
, что должно произойти, это:
- Если
W1
находится в своей начальной точке (т.е. ничего не делает), он начнет бежать к W2
.
- Если
W1
уже уже бежит к W2
(т.е. выполняет свою задачу), то, как только он достигнет W2
, он подаст сигнал W2
, чтобы начать, немедленно вернуться к его начальная точка и, поскольку StartWork
был вызван, снова начинайте бежать к W2
.
- Когда
W1
достигнет начальной точки W2
, он немедленно вернется к своей исходной точке.
- Если
W2
просто сидит, он немедленно побежит к W3
.
- Если
W2
уже движется в направлении W3
, то W2
просто пойдет снова, когда достигнет W3
и вернется к своей начальной точке.
Вышесказанное, вероятно, немного запутано и плохо написано.Но, надеюсь, вы получите основную идею.Очевидно, что эти рабочие будут работать в своих собственных потоках.
Кроме того, я полагаю, возможно, эта функциональность уже где-то существует?Если это так, определенно дайте мне знать!